首页 > 解决方案 > Python中的Vigenere密码不适用于大写/小写字母转换

问题描述

作为我目前正在参加的 CS50 哈佛编程课程的一部分,我正在做一个名为“Vigenere”的练习。

Vigenere 的密码应该有一个密钥作为输入,例如“abcd”。这将根据密钥中的每个字符对任何明文进行编码,其中 a = 0 和 b = 1 等。因此,带有明文“aa!aa”的密钥“abcd”将给出“ab!cd”。如果明文比密钥长,则密钥应该循环回 [0] 并重新开始,直到明文全部被编码。然而,非字母字母应该正常打印出来。

我的程序做的一切都是正确的(它逐行进行并且符合预期的行为),除非我收到以大写字母后跟小写字母开头的输入我的程序用小写键打印一个不同的字母然后它应该给我. 例如:键:“Baz”。明文:“aaa”。结果:“bgz”应该返回“baz”。

一直在谷歌搜索,调试,但就是想不通。也尝试过很多其他不同的方式,但我就是无法让它发挥作用。(对不起,复制粘贴,你可能会注意到我已经发布了一个类似的问题,但是那是在 C 中(这是 python),它是另一种错误)

代码:

import sys

if len(sys.argv) != 2 or not sys.argv[1].isalpha():
    print("usage: python vigenere.py keyword")
    sys.exit()

cipher = sys.argv[1]
plaintext = input("plaintext: ")

j = 0

def code(j):
    for key in cipher:
        if key.islower():
            return ord(cipher[j]) - 97
        if key.isupper():
            return ord(cipher[j]) - 65

print("ciphertext: ", end="")

for letters in plaintext:
    if letters.islower():
        print(chr(((ord(letters) - 97 + code(j)) % 26) + 97), end="")
        j += 1
    if letters.isupper():
        print(chr(((ord(letters) - 65 + code(j)) % 26) + 65), end="")
        j += 1
    if j == len(cipher):
        j = 0
    if not letters.isalpha():
        print(letters, end="")

print("")

标签: pythoncs50vigenere

解决方案


您的代码中的问题是由您的code函数引起的。

在其中,您使用 line for key in cipher:,然后使用if key.islower():or进行检查if key.isupper():

问题是每次我们进入code函数时,由于for循环,我们检查密码中的第一个字母是大写还是小写。

例如。对于密码“Baz”,j = 0,我们检查 B 是否为上/下,并获得上。我们立即返回大写 B

对于密码“Baz”,j = 1,我们检查 B 是否为上/下,并获得上。我们立即返回上 A。(当我们应该检查上/下的 a,并返回下 a!)


这个问题是通过检查密码的正确字母的大小写来解决的,并且可以通过替换来修复for key in cipher:key = cipher[j]如下面的块:

def code(j):
    key = cipher[j]
    if key.islower():
        return ord(key) - 97
    if key.isupper():
        return ord(key) - 65

进行更改后,对于以下输入:

密码=“BazBgh”明文=“aaaaAa”

我们得到

密文:bazbGh


推荐阅读