My vigenere cipher only gives me a coherent sentence when i remove all the spaces in the message and keyL. if i add them back and try to write my own code to account for it i get gibberish. im 90% sure this is due to me making an error when im trying to align the keyL to message so that it is the same length as message and has the same spaces in the same spots. can someone help me understand what i need to add in that will properly account for the spaces without making whats currently actually working properly dysfunctional?
message = 'txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztcgcexxch!'.replace(' ', '')
key = 'friends'
def decryption(message, key):
alpha = 'abcdefghijklmnopqrstuvwxyz'
punc = '.,/?!@#%^&*":'
keyL = ''.replace(' ', '')
for i in range(len(message)):
if message[i] == ' ':
keyL += ' '
else:
keyL += key[i % len(key)]
letter_to_index = dict(zip(alpha, range(len(alpha))))
index_to_letter = dict(zip(range(len(alpha)), alpha))
decrypted = ''
i = 0
for char in message:
if char in punc:
decrypted += char
else:
number = ((letter_to_index[char]) + (letter_to_index[keyL[i]])) % len(alpha)
decrypted += (index_to_letter[number])
i += 1
return decrypted
print(decryption(message, key))
OUTPUT:
youwereabletodecodethis?nicework!youarebecomingquitetheexpertatcrytography!
EXPECTEDOUTPUT:
you were able to decode this? nice work! you are becoming quite the expert at cryptography!
This loop is generating an invalid value for
keyL:Print out the value of
keyLafter this loop and you will see:Look carefully and you'll see that there are missing letters. Instead of
friendsfriendsfriendsyou havefrindsfiendfrends. This is happening because you're incrementingifor every loop iteration, but only extendingkeyLwhen the character is not a space.When you use this string to decrypt the message, you get invalid results.
There are several ways of fixing this up. Your existing code is doing a lot of extra work; you could reduce it to something like:
The only real magic here is the use of
itertools.cycle, which gives us an iterator that for each call tonext()will return the next character inkey, restarting back at the beginning when we reach the end.Note also that we don't need
index_to_letter, because we can access a string with a numeric index. If we have a string variable likeascii_lowercase = 'abcdefghijklmnopqrstuvwxyz', thenascii_lowercase[0]isa, and so forth.Using something closer to your original logic, we could do this instead: