2016-03-01 4 views
-2

Так что я пытаюсь сделать шифр vigenere (или что-то подобное) для моей работы GCSE. Однако одна из проблем, с которыми я столкнулась, заключается в том, что мой индекс списка всегда выходит за пределы диапазона, но код, который у меня есть, точно такой же, как и раньше, и ошибок не было. Это мой код:Python повторный индекс индекса вне диапазона

#Encrypting 
def encrypt(): 
    #>Creating initial variables 
    plainText = str(input('Input your plain text \n --> ')).upper() 
    key = str(input('Input your key. Make sure it is as long as your plain text. \n --> ')).upper() 

    #>Looping key 
    if len(key) < len(plainText): 
     key = len(plainText)*key 
    else: 
     key = key 

    #>Creating lists for ASCII values of each letter 
    plainAscii=[ord(i) for i in plainText] 
    keyAscii=[ord(k) for k in key] 

    #>Shortening the keyAscii list 
    while len(keyAscii) != len(plainAscii): 
     keyAscii.pop(len(keyAscii) - 1) 

    #>Adding the values together and putting them into a new list 
    cipherAscii=[] 
    x = 0 
    while x < len(key): 
     item = (plainAscii[x] + keyAscii[x]) - 75 
     cipherAscii.append(item) 
     x = x + 1 

    #>Making sure all numbers are within the 65 - 90 window 

    newCipher=[] 
    for c in cipherAscii: 
     if c > 90: 
      c = c - 26 
      newCipher.append(c) 
     elif c < 65: 
      c = c + 26 
      newCipher.append(c) 
     else: 
      newCipher.append(c) 

    #>Converting the ASCII back into regular letters 
    cipherText=[chr(i) for i in newCipher] 

    #>Printing the cipher text 
    for i in cipherText: 
     print (i, end="") 

Является ли мой код неправильным? Пожалуйста, помогите в ближайшее время, так как у меня мало времени.

+4

Было бы полезно, чтобы сообщить нам строку, где проблема происходит – flakes

+6

Было бы полезно, если вы при условии полной ошибки Traceback и указал точно, в какой строке соответствует последний номер строки. Кроме того, укажите пример ввода, фактический вывод и ожидаемый результат. –

+1

Что означает 'key = len (plainText) * key'?Если вы хотите обрезать ключ до длины обычного текста, используйте клавишу «key» [: len (plaintext)] ' –

ответ

0

Я просто заметил, что мой предыдущий ответ неверен, поэтому я отправляю новый ...

Проблема не с тем, как вы заполняют ключ, это намного проще: вы набираете keyмного, затем создайте ASCII-версию ключа, keyAscii, обрезаете , чтобы версия была верной, но затем петля для каждого символа в еще более длинном key.

Чтобы исправить это, все, что вам действительно нужно сделать, это изменить условие цикла к

while x < len(keyAscii): 

или обрезать key до нужной длины перед тем преобразование в ASCII:

# trim after padding 
if len(key) > len(plainText): 
    key = key[:len(plainText)] 

Также , вам не нужно вводить ключ так же: Как указано в другом (теперь удаленном) ответе, вам просто нужно повторить ключ ceil(len(text)/len(key)) раз, то есть

key = key * int(math.ceil(len(text)/len(key))) 

Кроме того, вы могли бы сделать вас работать намного проще с помощью itertools.cycle и zip:

def encrypt(plaintext, key): 
    cipherText = ((p + q) - 75 for (p, q) in zip(map(ord, plaintext), 
               map(ord, itertools.cycle(key)))) 
    cipherText = ((c - 65) % 26 + 65 for c in cipherText) 
    return ''.join(map(chr, cipherText)) 
1

Проблема, кажется, эта часть:

if len(key) < len(plainText): 
    key = len(plainText)*key 

Умножив key с len(plainText), вы повторяете ключ. Это вызывает проблемы позже, в цикле, где x может получить гораздо больше, чем len(plainText)

while x < len(key): 
    item = (plainAscii[x] + keyAscii[x]) - 75 

Вместо этого, вы хотите обрезать ключ к одной и той же длины, что и обычный текст.

if len(key) < len(plainText): 
    key = key[:len(plainText)] 

Простой демо:

>>> 3 * "abcde" 
'abcdeabcdeabcde' 
>>> "abcde"[:3] 
'abc' 
Смежные вопросы