我的vigenere密码加密功能出了什么问题? [英] What's wrong with my vigenere cypher encrypt function?

查看:76
本文介绍了我的vigenere密码加密功能出了什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I get the error string index out of range inside of the encrypt function I don't know how to get rot to repeat over text. the code only works when both inputs are the same length. i want to keep the alphabet_position and the rotate_character functions the same if i can.

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

推荐答案

通过在程序第36行的 rot [i] 中使用迭代器,您将越界.> i 将达到您的纯文本长度,该长度可以大于键.

You are going out-of-bounds by using the iterator in rot[i] in line 36 of your program - i will go up to the length of your plaintext, which can be larger than the key.

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

Try doing a module-div by length of the key, that way you should wrap around the key nicely:

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

编辑您仍然对脚本返回的结果不满意,因此我进行了更深入的探讨.潜在的问题是您正在尝试实现Vigenere的某些在线工具所称的增强模式":不能保证明文和密文都不来自 [a-zA-Z] ,但是可能特殊字符",例如 [0-9] 中的元素或< space> < 等字符之类的字符

Edit You were still unhappy with the result your script returned, so I dug a bit deeper. The underlying problem is that you are trying to implement what some online-tools for Vigenere call "enhanced mode": neither plain- nor ciphertext are guarenteed to be from [a-zA-Z], but may "special characters", e.g. elements from [0-9] or characters like <space>, <, etc.

如果您的脚本遇到特殊字符,它将不会旋转它,而是按原样复制它,就像在 rotate_character else 分支中所做的那样;这是对的.但是,在 encrypt()中,您为遇到的纯文本的每个符号使用了我们称为键符号"的符号.这意味着您实际上是在浪费"纯文本符号上的密钥符号,而该符号完全不会被加密(俗称旋转).

In case your script encounters a special character, it will not rotate it, but rather copy it over as-is, as done in the else-branch of rotate_character; this is correct. In encrypt(), however, you consume what we shall call a "keysymbol" for every symbol of the plaintext you encounter. This means that effectively you are "wasting" a keysymbol on a plaintext symbol that will not be encrypted (vulgo rotated) at all.

一旦意识到这一点,解决方法就很明显:当我们遇到特殊字符时,将其复制到输出列表中,但不要提前键流.仅在我们确实需要使用键符号的情况下才应提前键流.

Once you realize this, the fix becomes evident: when we encounter a special character, copy it over into the output list, but don't advance the keystream. The keystream should only be advanced if we actually need to consume a 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))

这篇关于我的vigenere密码加密功能出了什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆