0

这是我必须做的:

用 Python 编写一个脚本,该脚本是英文文本的 Vigenere 密码的一个版本的实现。你的脚本应该区分小写和大写字母(即加密密钥和明文允许由小写和大写字母组成,但密文应为大写)。除字母外,明文中还会有其他四个字符:逗号 (26)、点 (27)、破折号 (28)、下划线 (29) 将加密功能更改为 mod 30 下。

您的脚本应该从标准输入读取并写入标准输出。它应该提示用户输入大小为 k 的加密密钥。不允许像标准 Vigenere 密码那样重复密钥。相反,我们将遵循基于分组密码的想法。基本上,明文和密文将具有与密钥大小相同的大小为 k 的块。如果密钥长度比明文短,则将​​前一个块的块大小为 k 的密文连接到密钥。以下是关键字为“Carbondale”且 k = 10 的示例:

Plaintext :  SIU_CS-Department_is_the_best
 Key       :  CarbondaleUIHAQBBDPTUZ,MUOUCX
 Ciphertext:  UIHAQBBDPTUZ,MUOUCXHTODQTPYUM

所以,我想知道如何处理多余字符“,”的部分。“/”“_”。这是进行加密的功能:

a = len(key)

b = len(text)

while (len(key1) <= len(text1)):

    for i in range(0,a):
        num1 = ord(text1[i+var])%97
        num2 = ord(key1[i+var])%97
        num3 = num1+num2
        if (num3 > 25):
            encr.append(num3%25)
        else:
            encr.append(num3)
        i + 1

    for i in range(0,a):
        encr1.append(chr(encr[i+var]+97))
        i + 1

    for i in range(0,a):
        key1.append(encr1[i+var])
        i + 1
    var = var + a
4

1 回答 1

0

您的代码当前存在以下问题(我假设 , var = 0, encr = [],encr1 = []key1 = list(key)发生text1 = list(text)在您发布的代码之前):

  1. while如果密钥比明文长,您的循环将永远不会开始,否则永远不会结束,因为您永远不会缩短text1(这样做会破坏您的索引);
  2. 您不需要在for循环中手动增加计数器(如果您愿意,i + 1没有分配有效地什么都不做,您需要i += 1);
  3. 使用 mod( %) 时,不需要检查 if num3 < 25;和
  4. 如果您设法将它们包括在内,请注意您列出的额外字符与指定的字符 ( "/" != "-") 不同。

而不是使用ordand chr,我会建立自己的字母表来循环,例如

from string import ascii_uppercase

alphabet = list(ascii_uppercase) + [",", ".", "-", "_"]

您可能会发现“标准” Vigenère 的这种实现很有帮助:

from itertools import cycle

def vigenere(plain, key, alphabet):
    for p, k in zip(plain, cycle(key)):
        index = alphabet.index(p) + alphabet.index(k)
        yield alphabet[index % len(alphabet)]

这是您修改后的实现的一些伪代码:

convert all text (plain, key) to upper case
create a list to hold output
split plain into blocks of length len(key)
for each block in plain:
    if it's the first block, use key to encode
    otherwise, use the last block of encoded text in output 
于 2014-02-01T11:04:56.993 回答