换位密码返回错误结果

Transposition Cipher returning wrong results

这是我从https://inventwithpython.com/hacking

得到的源代码
import math, pyperclip

def main():
    myMessage = 'Cenoonommstmme oo snnio. s s c'
    myKey = 8

    plaintext = decryptMessage(myKey, myMessage)
    print(plaintext + '|')
    pyperclip.copy(plaintext)

def decryptMessage(key, message):
    numOfColumns = math.ceil(len(message) / key)
    numOfRows = key
    numOfShadedBoxes = (numOfColumns * numOfRows) - len(message)

    plaintext = [''] * int(numOfColumns)

    col = 0
    row = 0

    for symbol in message:
        plaintext[col] += symbol
        col += 1 


        if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
            col = 0
            row += 1

    return ''.join(plaintext)

if __name__ == '__main__':
    main()

这应该返回的是 Common sence is not so common.|

我得到的是 Coosmosi seomteonos nnmm n. c|

我无法弄清楚代码无法发回短语的位置

代码没问题。问题是您使用了错误版本的 Python。正如该网站的 'Installation' 章节所说:

Important Note! Be sure to install Python 3, and not Python 2. The programs in this book use Python 3, and you’ll get errors if you try to run them with Python 2. It is so important, I am adding a cartoon penguin telling you to install Python 3 so that you do not miss this message:

您正在使用 Python 2 至 运行 程序。

结果不正确,因为程序所依赖的功能在 Python 2 中的行为与在 Python 3 中的行为不同。具体来说,将 Python 3 中的两个整数相除会产生 floating-point 结果,但在 Python 2 中它产生 rounded-down 整数结果。所以这个表达式:

(len(message) / key)

在 Python 3 中产生 3.75 但在 Python 2 中产生 3,因此这个表达式:

math.ceil(len(message) / key)

在 Python 3 中产生 4(3.75 舍入为 4)但在 Python 2 中产生 3(3 舍入为 3)。这意味着您的 numOfColumns 不正确因此解密过程产生了错误的结果。

您可以通过将 (len(message) / key) 更改为 (float(len(message)) / key) 来强制 Python 2 将该计算视为 floating-point 除法来解决此特定问题,从而得到所需的 3.75结果。但真正的解决方案是切换到使用 Python 3,因为 Python 3 和 Python 2 之间的这些行为差异只会在您继续执行其余部分时继续造成麻烦书。