Python 中的 Vigenere 密码

Posted

技术标签:

【中文标题】Python 中的 Vigenere 密码【英文标题】:Vigenere Cypher in Python 【发布时间】:2016-02-13 04:05:13 【问题描述】:

我正在尝试用 Python 编写一个 vigenere 应用程序。这是应用程序应该运行的方式:

    运行程序 输入“1”加密或“2”解密消息 输入您的密码 输入要加密/解密的输入明文文件 输入将存储现在加密/解密文本的输出文件

密码密钥是一串字母数字chars,然后转换为int,该数字用于将纯文本旋转为密码文本。例如:Aa向右旋转一个字母加密或向左旋转一个字母解密。

几乎一切正常。如果我输入一个英文纯文本文件,对其进行加密,然后使用相同的密钥解密该文件,输出文件应该看起来与我开始使用的纯文本文件完全一样......并且除了换行符之外它确实如此.一些原来的换行符消失了,一些新的换行符被扔进去了。

我花了很长时间试图了解我做错了什么。我将不胜感激。这是完整的代码:

# ask user if he/she wishes to encrypt or decrypt a message
pmode = 0
while True:
    try:
        pmode = int(input("Enter 1 to encrypt or 2 to decrypt a message: "))
        while pmode not in 1, 2:
            int(input("Oops! Please enter 1 or 2: "))
            break
        break
    except (ValueError, NameError):
        print("Oops! That entry is not supported, try again...")

# ask user for a cypher keyword
key = input("Enter codeword: ")

# create list to store converted key
keylength = len(key)
realkey = [] * keylength

# convert "key" from string of chars to string of ints
for i in key:
    if i.isalpha():
        if i.isupper():
            realkey.append(ord(i) % ord('A') + 1)
        elif i.islower():
            realkey.append(ord(i) % ord('a') + 1)
    elif ord(i) >= 48 and ord(i) <=57:
        realkey.append(int(i))
    else:
        realkey.append(0)

# prompt user for input file and open it
infile_name = input("Enter input file name: ")
infile = open(infile_name, 'r')

# prompt user for output file and open it
outfiler_name = input("Enter output file name: ")
outfile = open(outfiler_name, "w")

# if on encryption mode, encrypt
if pmode == 1:
    # iterate over inmessage and rotate (within ASCII chars 32 - 126) using realkey
    indx = -1
    # loop over infile, encrypt and write to outfile
    while True:
        # temp variable to store current char
        char = infile.read(1)
        indx += 1
        # stop when EOF is reached
        if not char:
            break
        else:
            if ord(char) + realkey[indx % keylength] > 126:
                outfile.write(chr((ord(char) - 126 + realkey[indx % keylength])))
            else:
                outfile.write(chr((ord(char) + realkey[indx % keylength])))
else:
    # iterate over inmessage and rotate (within ASCII chars 32 - 126) using realkey
    indx = -1
    # loop over infile, encrypt and write to outfile
    while True:
        # temp variable to store current char
        char = infile.read(1)
        indx += 1
        # stop when EOF is reached
        if not char:
            break
        else:
            if ord(char) + realkey[indx % keylength] < 32:
                outfile.write(chr((ord(char) + 126 - realkey[indx % keylength])))
            else:
                outfile.write(chr((ord(char) - realkey[indx % keylength])))

# close files
infile.close()
outfile.close()

谢谢。

【问题讨论】:

【参考方案1】:

因为\n(换行符)是ascii 10,所以请记住ord('\n') == 10

此时你有两种可能性

    ord(char) + realkey[indx % keylength] &lt; 32: 通常为真,除非ord(key_letter)-ord('a') &gt;= 22 如果它是真的(比如 'a'(1 的 real_key 值),那么 10+126+1 = 137(或 '\x89') 现在,当我们稍后尝试使用相同的 key_letter 再次对其进行解码时 ord('\x89') == 137 所以我们的 ord(char) + realkey[indx % keylength] &lt; 32: 的 if 语句是假的 我们将使用 else 规则对其进行解码 89 - 1 ,这肯定不会让我们回到 10,因此这已将字符串解码错误 不然的话,这个案子就更惨了……

我想答案是你的算法在很多情况下都会崩溃......并且应该完全重构......我会给你一些关于重构它的建议,这将有助于让它对你更可测试

在测试硬编码您的用户密钥时key="Yellow55" 同样对你的字符串进行硬编码以加密和解密,确保它有一些更难的字符(如换行符)my_string="Hello\nTest\t\rString\r\n" ...真的只使用string.printable 会很聪明,因为它应该包括所有的 ascii 字母作为测试用例... 使用函数...我怎么强调都不为过!!!

功能

def decrypt(string_to_decrypt,key):
    #do your stuff
def encrypt(string_to_encrypt,key):
    #do your stuff

你应该使用for i,value in enumerate(my_list):而不是while True: i+=1 ...

打印东西……很多……我的意思是……打印出所有东西,这几乎总是会让你的错误非常明显

如果由于某种原因您无法打印所有内容,那么至少使用调试器

【讨论】:

这很有帮助。我看到我的错误不仅仅是缺少ord('\n') == 10,而是我有严重的设计问题。谢谢!

以上是关于Python 中的 Vigenere 密码的主要内容,如果未能解决你的问题,请参考以下文章

Python中的Vigenere密码不适用于大写/小写字母转换

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

Python:解码使用仿射密码编码的 Vigenere 密码

python 用Python实现的Vigenere密码。

python 简单的加密/解密算法(Vigenere密码)

用 Python 简化 Vigenere 密码程序