2017-03-17 11 views
1

나는 Vigenere 암호를 만들려고합니다. 메시지를 암호화하려고하면 다음 오류가 발생합니다.파이썬 Vigenere 튜플 오류

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

어떤 오류가 발생했는지 확실하지 않습니다.

당신이 python2.x을 사용하고있는 것으로 보인다
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. 
+1

난 당신의 코드를 실행 취소 들여 쓰기를 반복하면서 첫까지 모든 것을 포함, I 라인 (28) 상에 IndentationError있어 후 라인 2에 IndentationError를 가지고 시도 . 그 줄을 한 칸 공백으로 들여 쓰기를 한 후에, 나는'NameError : name 'baseAlphabet'not defined'을 얻었습니다. 실제로 문제를 나타내는 [mcve]를 게시하십시오. – Kevin

+0

'keyList [keyIncrement] 또는'plainTextChar'는'baseAlphabet'에 없습니다. 정확히 어떤 값이 실패했는지 알아 내려면 문제 해결을해야합니다. – glibdud

+1

코드를 편집 해 주셔서 감사합니다. 그것은 지금 나를 위해 달린다. 파이썬 2를 사용하여 실행하고 첫 번째 프롬프트에는''foo "'를, 두 번째 프롬프트에는''bar"'를 입력하면 충돌없이 실행되고'gof'가 출력됩니다. 프로그램을 중단시키기 위해 입력 한 입력 내용을 설명하십시오. – Kevin

답변

0

baseAlphabet에없는 char의 인덱스를 가져올 때마다 ValueError: tuple.index(x): x not in tuple 오류가 발생합니다. 따라서 key에는 이러한 문자 만 포함되어야하고 plainText을 인코딩 할 때는 "불량"문자 인코딩을 피하고 그대로 completeCipherText 목록에 복사하거나 유효한 baseAlphabet 문자로 변환해야합니다.

전통적인 암호화에서는 모든 공백과 구두점을 다른 문자 (예 : 'x' 또는 '.')로 변환하는 것이 일반적이었습니다. 나는 에 '.'을 추가하고 작은 기능 fix_string을 작성하여 해당 작업을 수행하기로 결정했습니다. fix_string 또한 모든 문자가 소문자임을 보장합니다.

나는 또한 코드에 대한 몇 가지 간단한 단순화를 만들었습니다.

baseAlphabet은 튜플 일 필요가 없습니다. 문자열을 사용할 수 있습니다. 당신이 하지만, 당신은 단지의 tuple 생성자에 문자열을 전달할 수 있습니다 전체에 그것을 밖으로 쓸 필요가 없습니다 단일 문자의 튜플을 사용하려면 예를 들어

tuple("some string") 
우리는 일반적으로 필요하지 않습니다

목록, 문자열 등과 같은 콜렉션의 길이를 추적하십시오. 내장 콜렉션은 모두 자체 길이를 추적하므로 len() 기능을 사용하여 해당 길이에 효율적으로 액세스 할 수 있습니다.

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. 
1

, 당신은 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를 사용할 수 있습니다.

희망이 도움이됩니다.