用 Python 简化 Vigenere 密码程序
Posted
技术标签:
【中文标题】用 Python 简化 Vigenere 密码程序【英文标题】:Simplifying Vigenere cipher program in Python 【发布时间】:2016-05-12 20:16:12 【问题描述】:我有下面的程序,它被传递给另一个函数,该函数简单地打印出原始和加密的消息。我想知道如何简化这个程序,特别是“match = zip”和“change = (reduce(lambda”) 行。如果可以在不使用 lambda 的情况下做到这一点,我该怎么做?
from itertools import cycle
alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
def vigenereencrypt(message,keyword):
output = ""
match = zip(message.lower(),cycle(keyword.lower()))
for i in match:
change = (reduce(lambda x, y: alphabet.index(x) + alphabet.index(y), i)) % 26
output = output + alphabet[change]
return output.lower()
【问题讨论】:
【参考方案1】:两件事:
-
你不需要有一个局部变量
match
,只需循环zip
您可以在 for 循环定义中拆分两个索引 x
和 y
,而不是使用 reduce
; reduce 通常用于较大的可迭代对象,由于 i
中只有 2 个项目,因此会增加不必要的复杂性。
即,您可以将 for 循环定义更改为:
for x, y in zip(...):
以及您对change
的定义:
change = (alphabet.index(x) + alphabet.index(y)) % 26
【讨论】:
【参考方案2】:从R Nar所说的开始:
def vigenereencrypt(message,keyword):
output = ""
for x, y in zip(message.lower(), cycle(keyword.lower())):
change = (alphabet.index(x) + alphabet.index(y)) % 26
output = output + alphabet[change]
return output.lower()
我们可以通过使用列表然后加入它来提高效率,而不是添加到字符串中,并且还可以通过注意输出已经是小写:
def vigenereencrypt(message,keyword):
output = []
for x, y in zip(message.lower(), cycle(keyword.lower())):
change = (alphabet.index(x) + alphabet.index(y)) % 26
output.append(alphabet[change])
return "".join(output)
然后我们可以将循环体减少到一行..
def vigenereencrypt(message,keyword):
output = []
for x, y in zip(message.lower(), cycle(keyword.lower())):
output.append(alphabet[(alphabet.index(x) + alphabet.index(y)) % 26])
return "".join(output)
...所以我们可以把它变成一个列表推导:
def vigenereencrypt(message,keyword):
output = (
alphabet[(alphabet.index(x) + alphabet.index(y)) % 26]
for x, y in zip(message.lower(), cycle(keyword.lower()))
)
return "".join(output)
我觉得我们可以用 map(alphabet.index, ...)
做一些事情,但我想不出比列表理解更好的方法。
【讨论】:
【参考方案3】:你可以用一堆索引而不是 zip 来做到这一点......
alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
alphaSort = k:n for n,k in enumerate(alphabet)
alphaDex = n:k for n,k in enumerate(alphabet)
def vigenereencrypt(message,keyword):
output = ""
#match = zip(message.lower(),cycle(keyword.lower())) # zip(a,cycle(b)) Creates [(a[n],b[n%len(b)]) for k in range(len(a)) ]
op = "" # So lets start with for k in range(len(a))
for k in range(len(message)):
op += alphaDex[(alphaSort[message.lower()[k]]+alphaSort[keyword.lower()[k%len(keyword)]])%len(alphabet)]
return(op)
【讨论】:
以上是关于用 Python 简化 Vigenere 密码程序的主要内容,如果未能解决你的问题,请参考以下文章
Python:解码使用仿射密码编码的 Vigenere 密码