Python Vigenere 元组错误

Python Vigenere tuple error

我正在尝试制作维吉尼亚密码。当我尝试加密消息时,出现以下错误。

    cipherCharIndexValue = baseAlphabet.index(keyList[keyIncrement]) + baseAlphabet.index(plainTextChar)
ValueError: tuple.index(x): x not in tuple

我不确定是什么问题导致了这个错误,有什么帮助吗?

baseAlphabet = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')

plainText = input("Please enter the plain text")
key = input("Please enter the key word")
keyList = []
keyLength = 0
while keyLength < len(plainText):
    #Adds the users entered key into a list character by character. 
    #Also makes the key the same length as plainText
    for char in key:
        if keyLength < len(plainText):
            keyList.append(str(char))
            keyLength = keyLength + 1

#The variable each processed letter is appended to
completeCipherText = [] 
#This is the value used to temporaily store the ciphertext character during the iteration
cipherCharIndexValue = 0
keyIncrement = 0

#iterates through the plain text
for plainTextChar in plainText:
        #Adds the base alphabets index value of the key and the plain text char
        cipherCharIndexValue = baseAlphabet.index(keyList[keyIncrement]) + baseAlphabet.index(plainTextChar)
        while cipherCharIndexValue > 25:
             #makes the addition value under 26 as to not go out of range of base alphabet tuple
            cipherCharIndexValue = cipherCharIndexValue - 26 
         #appends the ciphertext character to the completeCipherText variable. 
         #The character is the index of the key + index of the       plainTextChar from baseAlphabet
        completeCipherText.append(baseAlphabet[cipherCharIndexValue])
         #Moves onto the next key
        keyIncrement = keyIncrement + 1
print ('').join(completeCipherText)#Makes the result a strings for printing to the console.

您似乎在使用 python2.x,您应该使用 raw_input 而不是 input

如果你输入的字符串中有空格或其他标点符号,你的代码会崩溃,所以我建议你在使用index之前确保keyList[keyIncrement]baseAlphabet中方法,如果它不在这个元组中,你会得到这个错误:

ValueError: tuple.index(x): x not in tuple

例如

if keyList[keyIncrement] in keyList:
    cipherCharIndexValue = baseAlphabet.index(keyList[keyIncrement]) + baseAlphabet.index(plainTextChar)

或者您可以使用 try/catch 捕获异常以调试您的代码。

希望对您有所帮助。

每当您尝试获取不在 baseAlphabet 中的字符的索引时,您将遇到 ValueError: tuple.index(x): x not in tuple 错误。因此,您需要确保 key 仅包含此类字符,并且在编码 plainText 时要么避免编码 "bad" 字符,而是将它们原封不动地复制到 completeCipherText 列表中,或者转换他们到一个有效的 baseAlphabet 字符。

在传统加密中,通常会将所有空格和标点符号转换为另一个字符,例如'x''.'。我决定将 '.' 添加到 baseAlphabet 并编写一个小函数 fix_string 来执行该操作。 fix_string 还确保所有字母均为小写。

我还对您的代码进行了其他一些小的简化。

baseAlphabet 不需要是元组。我们可以使用字符串。但是如果你 do 想要使用单个字符的元组,则无需将其完整写出,你可以将字符串传递给 tuple 构造函数,例如

tuple("some string")

我们通常不需要跟踪列表、字符串等集合的长度。所有内置集合都跟踪它们自己的长度,我们可以使用 [=27= 高效地访问该长度] 功能。

我们不需要 keyIncrement。相反,我们可以使用 zip 函数并行遍历 keyListplainText 的字符。

我们可以使用 % 取模运算符,而不是使用循环来确保密钥和纯文本索引的总和在正确的范围内。

from __future__ import print_function

baseAlphabet = 'abcdefghijklmnopqrstuvwxyz.'

# Process s so that it only contains chars in baseAlphabet
def fix_string(s):
    # Convert to lower case
    s = s.lower()
    # Convert "other" chars to dot
    a = [ch if ch in baseAlphabet else '.' for ch in s]
    return ''.join(a)

# Vignere cipher
# mode = 1 to encode, -1 to decode
def vignere(plainText, key, mode):
    keyList = []
    while len(keyList) < len(plainText):
        # Adds the key into a list character by character. 
        # Also makes the key the same length as plainText
        for char in key:
            if len(keyList) < len(plainText):
                keyList.append(str(char))

    # The variable each processed letter is appended to
    completeCipherText = []

    # iterates through the plain text
    for keyChar, plainTextChar in zip(keyList, plainText):
        # Adds the base alphabet's index value of the plain text char and the key char
        cipherCharIndexValue = baseAlphabet.index(plainTextChar) 
        cipherCharIndexValue += mode * baseAlphabet.index(keyChar)
        # makes the addition value in range(len(baseAlphabet))
        cipherCharIndexValue = cipherCharIndexValue % len(baseAlphabet)

        # appends the ciphertext character to the completeCipherText variable. 
        # The character is the index of the key + index of the plainTextChar from baseAlphabet
        completeCipherText.append(baseAlphabet[cipherCharIndexValue])

    # Makes the result a string
    return ''.join(completeCipherText)

# Test

# plainText = raw_input("Please enter the plain text")
# key = raw_input("Please enter the key word")

plainText = 'This, is a test string!'
key = 'the key'

# Process plainText and key so that they only contain chars in baseAlphabet
plainText = fix_string(plainText)
key = fix_string(key)

ciphertext = vignere(plainText, key, 1)
print(ciphertext)

decoded = vignere(ciphertext, key, -1)
print(decoded)

输出

lomrjdfkgezciplgwsamkzg
this..is.a.test.string.