Python中的凯撒密码函数
我正在尝试用Python创建一个简单的凯撒密码函数,这个函数会根据用户输入的内容来移动字母,并在最后生成一个新的字符串。唯一的问题是,最后生成的加密文本只显示了最后一个移动的字符,而不是包含所有移动字符的完整字符串。
这是我的代码:
plainText = raw_input("What is your plaintext? ")
shift = int(raw_input("What is your shift? "))
def caesar(plainText, shift):
for ch in plainText:
if ch.isalpha():
stayInAlphabet = ord(ch) + shift
if stayInAlphabet > ord('z'):
stayInAlphabet -= 26
finalLetter = chr(stayInAlphabet)
cipherText = ""
cipherText += finalLetter
print "Your ciphertext is: ", cipherText
return cipherText
caesar(plainText, shift)
27 个回答
11
这是对@amillerrhodes的回答中代码的改进版本,这个版本可以处理不同的字母表,而不仅仅是小写字母:
def caesar(text, step, alphabets):
def shift(alphabet):
return alphabet[step:] + alphabet[:step]
shifted_alphabets = tuple(map(shift, alphabets))
joined_aphabets = ''.join(alphabets)
joined_shifted_alphabets = ''.join(shifted_alphabets)
table = str.maketrans(joined_aphabets, joined_shifted_alphabets)
return text.translate(table)
使用示例:
>>> import string
>>> alphabets = (string.ascii_lowercase, string.ascii_uppercase, string.digits)
>>> caesar('Abc-xyZ.012:789?жñç', step=4, alphabets=alphabets)
'Efg-bcD.456:123?жñç'
参考资料:
关于 str.maketrans
的文档。
关于 str.translate
的文档。
关于 string
库的文档
21
你需要把 cipherText = ""
这行代码放到 for 循环的前面。因为你每次循环的时候都在重置它。
def caesar(plainText, shift):
cipherText = ""
for ch in plainText:
if ch.isalpha():
stayInAlphabet = ord(ch) + shift
if stayInAlphabet > ord('z'):
stayInAlphabet -= 26
finalLetter = chr(stayInAlphabet)
cipherText += finalLetter
print "Your ciphertext is: ", cipherText
return cipherText
62
我知道这个回答并没有直接解决你的问题,但我觉得它还是很有帮助的。这里有一种用字符串方法实现凯撒密码的替代方法:
def caesar(plaintext, shift):
alphabet = string.ascii_lowercase
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)
实际上,由于字符串方法是用C语言实现的,所以这个版本的性能会更好。我认为这就是所谓的“Pythonic”做法。