python - 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("")
解决方案
您的代码中的问题是由您的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
推荐阅读
- optimization - 将 CVRP 的条件子旅游消除转换为正常的子旅游消除
- java - 如何使用 json 文件显示自动完成字段的建议?
- java - 在换行符上输出
- android - 无法从以下 uri 获取位图:Uri imageUri = data.getClipData().getItemAt(i).getUri()
- python - 从数据框中获取文本的最佳方法,按句子然后按单词进行标记
- ios - 自定义栏按钮项目图像框架太宽
- php - php-fpm主进程重启后执行PHP脚本
- oracle - 无法删除 sql developer 中的现有主表
- linux - 我试图通过串口发送命令列表,但设备只占用第一行,其他行被忽略
- javascript - 声明一个全局 google maps 对象