凯撒密码 - ASCII 字符的环绕方法通过教科书更容易混淆

Caesar Cipher - Wraparound Method for ASCII Characters More Confusing via Textbook

我了解凯撒密码方法并使用模运算符成功编写了自己的环绕,但我不了解我正式学习教科书中显示的方法。我指的是我在下面评论的代码:

plainText = input("Enter a one-word, lowercase message: ")
distance = int(input("Enter the distance value: "))
code = ""
for ch in plainText:
    ordvalue = ord(ch)
    cipherValue = ordvalue + distance
    #confusion begins here
    if cipherValue > ord('z'):
        cipherValue = ord('a') + distance - \
            (ord('z') - ordvalue + 1)
    #confusion ends here
    code += chr(cipherValue)
print(code)

如果你考虑一下它是有道理的,即使它是一种稍微冗长和复杂的计算方法。唉,表达式的复杂程度没有限制,只有表达式的简单程度没有限制。

所以 ord('a')ord('z') 的值为 97 和 122。当我们得到 ord(char) + distance = 123, 时,我们想将它映射回 ord('a'),对吧。所以我们接着需要减去允许的字符间隔的长度。此间隔的大小为 ord('z') - ord('a') + 1(+1,因为两个端点实际上都是间隔和允许值的一部分)。

结果公式将是(假设ordValue + distance > ord('z')

cipherValue = ordValue + distance - (ord('z') - ord('a') + 1) 
            = ordValue + distance - ord('z') + ord('a') - 1
            = ord('a') + distance - ord('z') + ordValue - 1
            = ord('a') + distance - (ord('z') - ordValue + 1)

...这是让你感到困惑的表达方式。

最后,这个方法有一个缺陷,它最多只能覆盖 ord('z') - ord('a') + 1 的溢出,所以如果 distance 比那个长,它就不会工作:

cipherValue = ordValue + distance - (ord('z') - ord('a') + 1) 
            = ordValue + (ord('z') - ord('a') + 2) - ord('z') + ord('a') - 1
            = ordValue + ord('z') - ord('a') + 2 - ord('z') + ord('a') - 1
            = ordValue + 1

现在,如果 ordValue 来自 ord('z'),那么我们就有麻烦了,因为密码值将是 ord('z') + 1 = 123,这与密文字母表中的字符不对应( chr(123) = '{').

也许我们可以假设 distance 不应该那么长或更长(这是有道理的),否则使用模表达式会更安全。