Python 中的 Vigenere 密码不适用于 uppercase/lowercase 字母转换
Vigenere cipher in Python not working for uppercase/lowercase letter conversion
作为我目前正在参加的 CS50 哈佛编程课程的一部分,我正在做一个名为 "Vigenere" 的练习。
Vigenere 的密码应该有一个密钥作为输入,例如 "abcd"。这将根据密钥中的每个字符对任何明文进行编码,其中 a = 0 和 b = 1 等。因此带有明文 "aa!aa" 的密钥 "abcd" 将得到 "ab!cd"。如果明文比密钥长,则密钥应该循环回到 [0] 并重新开始,直到明文全部被编码。但是,非字母应该可以正常打印出来。
我的程序做的一切都正确(它逐行进行并且满足预期的行为)除了当我收到以大写字母开头后跟小写字母的输入时我的程序使用小写键打印不同的字母那么它应该给我。例如:键:"Baz"。明文:"aaa"。结果:"bgz" 它应该 return "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("")
您的代码中的问题是由您的 code
函数引起的。
在其中,您使用行 for key in cipher:
,然后使用 if key.islower():
或 if key.isupper():
检查它。
问题是每次我们进入code
函数时,由于for循环,我们只检查密码中的第一个字母是大写还是小写案例.
eg. for cipher 'Baz', j = 0, we check if B is upper/lower, and get upper. We immediately return uppercase B
For cipher 'Baz', j = 1, we check if B is upper/lower, and get upper. We immediately return upper A. (When we should be checking a for upper/lower, and returning lower 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
进行更改后,对于以下输入:
cipher = "BazBgh"
plaintext = "aaaaAa"
我们得到
ciphertext: bazbGh
作为我目前正在参加的 CS50 哈佛编程课程的一部分,我正在做一个名为 "Vigenere" 的练习。
Vigenere 的密码应该有一个密钥作为输入,例如 "abcd"。这将根据密钥中的每个字符对任何明文进行编码,其中 a = 0 和 b = 1 等。因此带有明文 "aa!aa" 的密钥 "abcd" 将得到 "ab!cd"。如果明文比密钥长,则密钥应该循环回到 [0] 并重新开始,直到明文全部被编码。但是,非字母应该可以正常打印出来。
我的程序做的一切都正确(它逐行进行并且满足预期的行为)除了当我收到以大写字母开头后跟小写字母的输入时我的程序使用小写键打印不同的字母那么它应该给我。例如:键:"Baz"。明文:"aaa"。结果:"bgz" 它应该 return "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("")
您的代码中的问题是由您的 code
函数引起的。
在其中,您使用行 for key in cipher:
,然后使用 if key.islower():
或 if key.isupper():
检查它。
问题是每次我们进入code
函数时,由于for循环,我们只检查密码中的第一个字母是大写还是小写案例.
eg. for cipher 'Baz', j = 0, we check if B is upper/lower, and get upper. We immediately return uppercase B
For cipher 'Baz', j = 1, we check if B is upper/lower, and get upper. We immediately return upper A. (When we should be checking a for upper/lower, and returning lower 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
进行更改后,对于以下输入:
cipher = "BazBgh" plaintext = "aaaaAa"
我们得到
ciphertext: bazbGh