'str'对象在caesar加密器中不可调用

时间:2016-05-23 12:33:16

标签: python string python-3.x encryption caesar-cipher

def encrypt_caesar(plaintext):
    s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    d = dict(map(s,s[3:]+ s[:3]))
    return ''.join(map(lambda l: d.get(l,l), plaintext.lower()))

尝试从斯坦福演讲幻灯片中复制此代码并运行它但它出现'str' object is not callable错误,我做错了什么?

1 个答案:

答案 0 :(得分:0)

我猜幻灯片的作者实际上没有测试代码。

您制作的代码正在尝试使用map()作为函数调用s

map(s,s[3:]+ s[:3])
#   ^ This must be a *callable object*, like a function

如果您想创建一个字典,将ASCII字母映射到字母表中的3个字母,请改用zip() function

d = dict(zip(s, s[3:] + s[:3]))

zip()然后将s中的每个元素与s[3:] + s[:3]中的每个元素配对,然后将这些(letter, letter + 3)对传递给dict()以形成关键字价值对:

>>> s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
>>> dict(zip(s, s[3:] + s[:3]))
{'A': 'D', 'I': 'L', 'L': 'O', 'X': 'A', 'N': 'Q', 'D': 'G', 'S': 'V', 'B': 'E', 'V': 'Y', 'C': 'F', 'K': 'N', 'W': 'Z', 'R': 'U', 'O': 'R', 'T': 'W', 'P': 'S', 'F': 'I', 'J': 'M', 'M': 'P', 'E': 'H', 'Q': 'T', 'H': 'K', 'G': 'J', 'Z': 'C', 'U': 'X', 'Y': 'B'}

接下来,您的最后一行将完全失败进行任何加密,因为您的地图只处理大写字母,但小写您的输入。要么生成小写地图,要么小写输入。

缩小地图可能如下所示:

def encrypt_caesar(plaintext):
    s = "abcdefghijklmnopqrstuvwxyz"
    d = dict(zip(s, s[3:] + s[:3]))
    return ''.join(map(lambda l: d.get(l, l), plaintext.lower()))

或者您可以使用string.ascii_lowercase constant

from string import ascii_lowercase

def encrypt_caesar(plaintext):
    d = dict(zip(ascii_lowercase, ascii_lowercase[3:] + ascii_lowercase[:3]))
    return ''.join(map(lambda l: d.get(l,l), plaintext.lower()))

然而,使用此方法相当慢。对于超快速的加密',请使用str.translate() method;最好使用str.maketrans生成输入地图:

from string import ascii_lowercase as alc

def encrypt_caesar(plaintext, shift=3):
    map = str.maketrans(alc, alc[shift:] + alc[:shift])
    return plaintext.lower().translate(map)

我添加了一个shift参数来定义应该应用多少字母移位。

我会将小写和大写字母作为练习留给读者!