我的vigenere cypher加密函数怎么了?

2024-04-25 00:21:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我得到的错误字符串索引超出了加密函数的范围,我不知道如何让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()

Tags: textinalphareturnifdefupperlower
1条回答
网友
1楼 · 发布于 2024-04-25 00:21:11

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

尝试按键的长度进行模块div,这样可以很好地环绕键:

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

编辑您对脚本返回的结果仍然不满意,所以我深入研究了一下。潜在的问题是,您正在尝试实现Vigenere的一些在线工具所称的“增强模式”:无论是纯文本还是密文都不保证来自[a-zA-Z],但可能是“特殊字符”,例如来自[0-9]的元素或<space><等字符

如果您的脚本遇到特殊字符,它不会旋转它,而是按原样复制它,就像rotate_characterelse-分支所做的那样;这是正确的。然而,在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))

相关问题 更多 >