I am making a Caesar cipher, and I get an out of index error when i run the code. It works and encrypts the message when it's a few letters, but when I enter in more than ten words it gives me an index error.
shift_key = int(raw_input("Enter in your key shift: 1-9\n>>> "))
alphabet = ['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']
encrypted_alphabet = []
encrypted_message = ''
for i in alphabet[shift_key:]:
encrypted_alphabet.append(i)
input = raw_input("Enter text to be decoded\n>>> ").upper()
input = input.split()
for i in input:
for j in i:
index = alphabet.index(j)
encrypted_message += encrypted_alphabet[index]
encrypted_message += ' '
print encrypted_message
The problem is in these two lines:
for i in alphabet[shift_key:]:
encrypted_alphabet.append(i)
Notice that doing alphabet[shift_key:]
slices the list alphabet
to only take those elements starting from shift_key
.
In other words, if shift_key
is 25, for example, then alphabet[shift_key:]
returns just ['Y','Z']
. Since you're appending these to encrypted_alphabet
, encrypted_alphabet
then becomes just ['Y','Z']
. But what you want is also the rest of the alphabet appended to the end of encrypted_alphabet
.
Simply put, the lengths of your encrypted_alphabet
and alphabet
mismatch.
You can correct it this very simply by
for i in alphabet[shift_key:] + alphabet[:shift_key]:
encrypted_alphabet.append(i)
or (even more simply)
encrypted_alphabet = alphabet[shift_key:] + alphabet[:shift_key]
If you want to know the right way to do this, however, use the inbuilt string method maketrans
instead, which is far simpler:
import string
shift_key = int(raw_input("Enter in your key shift: 1-9\n>>> "))
alphabet = string.ascii_uppercase
encrypted_alphabet = alphabet[shift_key:] + alphabet[:shift_key]
caesar = string.maketrans(alphabet,encrypted_alphabet)
input = raw_input("Enter text to be decoded\n>>> ").upper()
print(input.translate(caesar))
Quick explanation
As the code indicates, maketrans
creates a translation table between two strings, mapping each character in the first to the other. You can then feed this translation table into the .translate()
method that every string has.