使用 ASCII 标点符号、数字和大写字母的凯撒加密?

Caesar encryption with ASCII punctuation, digits, and uppercase letters?

尝试使凯撒密码函数包括 ASCII 大写字母、数字和标点符号,而不仅仅是小写字母。 所以像“hello1?”这样的句子向前推一个键会变成“ifmmp2@”,因为 ASCII 标点符号列表的顺序是:!"#$%&'()*+,-./:;<=>?@[]^_`{| }~

到目前为止,这是我的代码:

from string import ascii_lowercase as letters
from string import punctuation
from string import digits

def encrypt(sentence, key):
    """
    key must be positive
    """
    print(f"Message: {sentence}")
    print(f"Key: {key}")
    enc = "".join(map(lambda x: ((2*letters)[letters.find(x) + key%len(letters)])
      ((2*punctuation)[punctuation.find(x) + key%len(punctuation)])
      ((2*digits)[digits.find(x) + key%len(digits)]) 
      if x in letters else x, sentence))
    print(f"Encrypt: {enc}\n")
    return enc

try:
    line = input().lower()
    key = int(input())
    assert key > 0
except:
    key = 5


secret = encrypt(line, key)

弹出的错误如下:

raceback (most recent call last):
  File "/Users/arkan/Desktop/Code:Data Vizualization/Math/Cryptography/Caesar2.py", line 25, in <module>
    secret = encrypt(line, key)
  File "/Users/arkan/Desktop/Code:Data Vizualization/Math/Cryptography/Caesar2.py", line 11, in encrypt
    enc = "".join(map(lambda x: ((2*letters)[letters.find(x) + key%len(letters)])
  File "/Users/arkan/Desktop/Code:Data Vizualization/Math/Cryptography/Caesar2.py", line 11, in <lambda>
    enc = "".join(map(lambda x: ((2*letters)[letters.find(x) + key%len(letters)])
TypeError: 'str' object is not callable

更正后的代码:

from string import ascii_lowercase as letters
from string import punctuation
from string import digits

def encrypt(sentence, key):
    """
    key must be positive
    """
    print(f"Message: {sentence}")
    print(f"Key: {key}")
    enc = "".join(map(lambda x: (((2*letters)[letters.find(x) + key%len(letters)]) if x in letters else "" +
      ((2*punctuation)[punctuation.find(x) + key%len(punctuation)]) if x in punctuation else "" +
      ((2*digits)[digits.find(x) + key%len(digits)]) if x in digits else "" ), sentence))
    print(f"Encrypt: {enc}\n")
    return enc

try:
    line = input().lower()
    key = int(input())
    assert key > 0
except:
    key = 5


secret = encrypt(line, key)

我已经检查过了,它有效!

注意:我也喜欢以混淆的方式编写代码,但是当您编写如此复杂的算法时,最好先以简单(可能很长)的方式编写代码,检查它是否有效,然后将其转换为映射、列表理解和 lambda。更容易调试。这些内置函数比更长的代码更快,所以最终产品最好是这样。