Python 中的 Vigenere 密码

Vigenere Cypher in Python

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

的方式
  1. 运行 程序
  2. 输入“1”加密或输入“2”解密消息
  3. 输入您的密钥
  4. 输入你要输入的明文文件encrypt/decrypt
  5. 输入将存储 now-encrypted/decrypted 文本的输出文件

密钥是一串字母数字 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()

谢谢。

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

此时你有2种可能

  1. ord(char) + realkey[indx % keylength] < 32:
    • 通常为真,除非 ord(key_letter)-ord('a') >= 22
    • 如果它是真的(比如 'a'(real_key 1 的值)那么 10+126+1 = 137(或 '\x89'
    • 现在,当我们稍后尝试使用相同的 key_letter 再次对其进行解码时
      • ord('\x89') == 137
      • 所以我们 ord(char) + realkey[indx % keylength] < 32: 的 if 语句是假的
      • 我们将使用我们的 else 规则对其进行解码 89 - 1 ,这肯定不会让我们回到 10,所以这对字符串进行了错误的解码
  2. 或者不是,这种情况更糟...

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

  • 在测试硬编码您的用户密钥时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
  • 而不是 while True: i+=1 ... 你应该使用 for i,value in enumerate(my_list):

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

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