Python中的凯撒密码函数

23 投票
27 回答
231660 浏览
提问于 2025-04-17 10:23

我正在尝试用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”做法。

撰写回答