我的 vigenere 密码加密功能有啥问题?

Posted

技术标签:

【中文标题】我的 vigenere 密码加密功能有啥问题?【英文标题】:What's wrong with my vigenere cypher encrypt function?我的 vigenere 密码加密功能有什么问题? 【发布时间】:2017-10-21 15:47:35 【问题描述】:

我得到的错误字符串索引超出了加密函数的范围我不知道如何让 rot 在文本上重复。该代码仅在两个输入长度相同时才有效。如果可以的话,我想保持字母位置和旋转字符功能相同。

alpha_lower_list = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", 
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
alpha_upper_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", 
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]   

def alphabet_position(letter):     
    if letter in alpha_upper_list:
        return alpha_upper_list.index(letter)
    else:
        return alpha_lower_list.index(letter)

def rotate_character(char, rot):
    rotated_letter = ''
    if char.isalpha():
        rotate = alphabet_position(char) + rot
        if rotate < 26:
            if char in alpha_upper_list:
                rotated_letter = alpha_upper_list[rotate]
                return(rotated_letter)
            else:
                rotated_letter = alpha_lower_list[rotate]
                return(rotated_letter)
        else:
            if char in alpha_upper_list:
                rotated_letter = alpha_upper_list[rotate % 26]
                return(rotated_letter)
            else:
                rotated_letter = alpha_lower_list[rotate % 26]
                return(rotated_letter)
    else:
        return(char)

def encrypt(text, rot):
    lis = []
    for i in range(len(text)):
        lis.append(rotate_character(text[i], alphabet_position(rot[i])))

    return (''.join(lis))

def main():
    user_text = input("Type a message: ")
    rotate_by = input("Rotate by: ")

    print(encrypt(user_text, rotate_by))

if __name__ == '__main__':
    main()

【问题讨论】:

【参考方案1】:

在程序的第 36 行使用 rot[i] 中的迭代器会越界 - i 将达到明文的长度,该长度可能大于密钥。

尝试按密钥的长度做一个 module-div,这样你应该很好地环绕密钥:

lis.append(rotate_character(text[i], alphabet_position(rot[i % len(rot)])))

编辑你仍然对你的脚本返回的结果不满意,所以我挖得更深了。根本问题是您正在尝试实现 Vigenere 的一些在线工具所称的“增强模式”:明文和密文都不能保证来自 [a-zA-Z],但可能是“特殊字符”,例如来自[0-9] 的元素或&lt;space&gt;&lt; 等字符。

如果你的脚本遇到特殊字符,它不会旋转它,而是照原样复制它,就像在rotate_characterelse-branch 中所做的那样;这是对的。然而,在encrypt() 中,您为遇到的明文的每个 符号使用我们称之为“keysymbol”的东西。这意味着您实际上是在“浪费”纯文本符号上的密钥符号根本不会被加密(vulgo 旋转)

一旦你意识到这一点,解决办法就很明显了:当我们遇到特殊字符时,将其复制到输出列表中,但不要推进密钥流。仅当我们确实需要使用密钥符号时,才应推进密钥流。

翻译成代码:

def encrypt(text, rot):
    lis = []
    keystream = 0
    for i in range(len(text)):
        keychar = keystream % len(rot)
        if text[i].isalpha():
            lis.append(rotate_character(text[i], alphabet_position(rot[keychar])))
            keystream += 1
        else:
            lis.append(text[i])

    return (''.join(lis))

【讨论】:

谢谢,我只需要弄清楚如何返回这个:'Feqwgba 您能否提供此加密有效输出的明文和密钥?这样可以轻松跟踪错误... 这是输入 vigenere.encrypt('Sailing 它应该打印出来:Feqwgba 这是我使用的:def encrypt(text, rot): lis = [] key = 0 for i in range(len(text)): if text[i].isalpha(): lis.append(rotate_character(text[i], alphabet_position(rot[key % len(rot)]))) if text[i] == " ": key = key -1 else: key +=1` ` else:` ` lis.append(text[ i])` `return (''.join(lis))`

以上是关于我的 vigenere 密码加密功能有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Vigenere 密码只能正确加密部分消息?

加密 Vigenere 密码

Java vigenere 密码性能问题

尝试加密和解密 vigenere 密码

Vigenere 密码破坏了一些

vigenere密码中的itertools循环导致空间问题python