我的vigenere cypher加密功能有什么问题?

时间:2017-10-21 15:47:35

标签: python encryption vigenere

我在加密函数内部得到错误字符串索引超出范围我不知道如何腐烂重复文本。代码仅在两个输入长度相同时才有效。我想保留alphabet_position和rotate_character函数,如果可以的话。

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 个答案:

答案 0 :(得分:0)

通过使用程序第36行rot[i]中的迭代器,您将超出范围 - i将达到明文的长度,该明文可能大于密钥

尝试按键的长度执行module-div,这样你就可以很好地回绕键:

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

编辑您仍然对脚本返回的结果不满意,所以我挖了一下。根本问题在于你正在尝试实现Vigenere调用的一些在线工具&#34;增强模式&#34;:普通密文和密文都不是来自[a-zA-Z],而是可以&#34;特殊字符&#34;,例如[0-9]中的元素或<space><等字符

如果您的脚本遇到特殊字符,它将不会旋转它,而是按原样复制它,就像在else - rotate_character的分支中所做的那样;这是对的。然而,在encrypt()中,你会消耗我们称之为&#34; keysymbol&#34;对于您遇到的明文的每个符号。这意味着你有效地浪费了#34;明文符号上的密钥符号,不会被加密(外包旋转)

一旦你意识到这一点,修复就会变得明显:当我们遇到一个特殊角色时,将其复制到输出列表中,但不要推进密钥流。如果我们确实需要使用keysymbol,那么密钥流应该只是前进。

翻译成代码:

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))