Python 中的 Vigenere 密码
Posted
技术标签:
【中文标题】Python 中的 Vigenere 密码【英文标题】:Vigenere Cypher in Python 【发布时间】:2016-02-13 04:05:13 【问题描述】:我正在尝试用 Python 编写一个 vigenere 应用程序。这是应用程序应该运行的方式:
-
运行程序
输入“1”加密或“2”解密消息
输入您的密码
输入要加密/解密的输入明文文件
输入将存储现在加密/解密文本的输出文件
密码密钥是一串字母数字chars
,然后转换为int
,该数字用于将纯文本旋转为密码文本。例如:A
或a
向右旋转一个字母加密或向左旋转一个字母解密。
几乎一切正常。如果我输入一个英文纯文本文件,对其进行加密,然后使用相同的密钥解密该文件,输出文件应该看起来与我开始使用的纯文本文件完全一样......并且除了换行符之外它确实如此.一些原来的换行符消失了,一些新的换行符被扔进去了。
我花了很长时间试图了解我做错了什么。我将不胜感激。这是完整的代码:
# 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] < 32:
通常为真,除非ord(key_letter)-ord('a') >= 22
如果它是真的(比如 'a'(1
的 real_key 值),那么 10+126+1 = 137(或 '\x89'
)
现在,当我们稍后尝试使用相同的 key_letter 再次对其进行解码时
ord('\x89') == 137
所以我们的 ord(char) + realkey[indx % keylength] < 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