'PYTHON 3 Vigniere decoder issue; even with code outputting spaces and punctuation correctly, after punctuation mark the decoder doesnt work

Working on a Vigniere Decoder in Python 3 but after processing punctuation marks (which output correctly) the decoding algorithm is thrown off, I assume this to be due to incorrect drawing of comparative index values (between encoded message string and repeated key phrase string).

To get around this I thought of including a punctuation counter for correction, but I do not know where in the maths of my nested if loop to implement this. Or if this (punctuation counter) is even a fix that will work in the method of logic I am using.

I'm only working with basic tools in Python as this is supposed to be a challenge of what I've learnt so far, so simpler/more advanced ways to program a Vigniere decoder might not be something I know, in case anyone sees my attempt and thinks what the hell are they doing!

import string
alphabet = (string.ascii_lowercase)
punctuation = (string.punctuation)

def vignieredecoder(message, key):
    keycompare = ''
    index = 0
    decodedmessage = ''

    #makes key repeat to length of message w/ spaces integrity the same
    
    for character in message:
        if character == ' ':
            keycompare += ' '
        else:
            keycompare += key[index % len(key)]
            index += 1
    key = keycompare
    

    # decoding loop

    for characters in range(len(message)):
        punctcount = 0
            
        if message[characters] in punctuation:
            decodedmessage += message[characters]
            punctcount += 1
                    
        elif message[characters] == ' ':
            decodedmessage += ' '
            
        else:
            # store index value of character in message, e.g. a = 0, b = 1, etc
            messageletterindexval = alphabet.index(message[characters])
            
            # store index value of character in keycompare[place of character in message], e.g. if key is friends and first iteration being 0 = f
            keycompareindex = key[characters]

            # access character in alphabet at indexvalue of keycompare, e.g. if key is friends and first iteration of for loop, finds f in alphabet and returns indexval 5
            keycompareindexval = alphabet.index(keycompareindex)
            
            
            decodedletterval = messageletterindexval - keycompareindexval
            
            if decodedletterval < 0:
                decodedletterval += 26
                decodedmessage += alphabet[decodedletterval]
            else:
                decodedmessage += alphabet[decodedletterval]
    return decodedmessage

print(vignieredecoder('dfc aruw fsti gr vjtwhr wznj? vmph otis! cbx swv jipreneo uhllj kpi rahjib eg fjdkwkedhmp!', 'friends' ))

terminal output: you were able to decode this? rzmp jcao! zjs bor wfxmnfab rpgub gcf zvqbeo bo asvgjhmyqel!

expected output: you were able to decode this? nice work! you are becoming quite the expert at crytography!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source