简体   繁体   中英

vigenere encryption probleme with 'spaces' on python

i can t pinpoint the reason why the encryption goes wrong after 'spaces' here is the code:

def chiffre_vigenere(message,key):
        message = message.lower()
        key = key.lower()
        encrypted = []
        d = dict(a=0,b=1,c=2,d=3,e=4,f=5,g=6,h=7,i=8,j=9,k=10,l=11,m=12,n=13,o=14,p=15,q=16,r=17,s=18,t=19,u=20,v=21,w=22,x=23,y=24,z=25)
        long_key = key
        while len(message) > len(long_key) :
                long_key = long_key + key
        i=0
        while i < len(message) :
                decalage = d.get(long_key[i])
                if message[i].isalpha() :            
                        c = ord(message[i]) + decalage
                        if c > 122 :
                                c = c - 26
                        encrypted.append(chr(c))
                else :
                        encrypted.append(message[i])       
                i = i+1
        print(listToString(encrypted))

for example when i do: chiffre_vigenere('stack overflow','apple') it gives: sipno dkpvfadh the first word is encrypted right but after the space the encryption is wrong any help is appreciated thanks in advance

The problem is that you're using the same counter variable i to mark your place in two different strings: message and long_key . Whenever you encounter a non-alphabet character in message , you're stepping to the next character, but you're also stepping to the next character in long_key , which is not what you want to do.

If you just use i to count characters in long_key then the problem goes away. For example:

def chiffre_vigenere(message,key):
    message = message.lower()
    key = key.lower()
    encrypted = []
    d = dict(a=0,b=1,c=2,d=3,e=4,f=5,g=6,h=7,i=8,j=9,k=10,l=11,m=12,n=13,o=14,p=15,q=16,r=17,s=18,t=19,u=20,v=21,w=22,x=23,y=24,z=25)
    long_key = key
    while len(message) > len(long_key):
        long_key = long_key + key
    i=0
    for ch in message:
        decalage = d.get(long_key[i])
        if ch.isalpha() :        
            c = ord(ch) + decalage
            if c > 122 :
                c = c - 26
            encrypted.append(chr(c))
            i = i+1
        else :
            encrypted.append(ch)
    print(listToString(encrypted))

You might also consider simplifying your code a little. You can use the ord function to convert ASCII values to integers, and a modulus operator to cycle through the values of key without having to expand it to the size of the input message.

def chiffre_vigenere(message,key):
    key = key.lower()
    encrypted = ''
    i = 0
    for ch in message.lower():
        if 'a' <= ch <= 'z':
            a = ord(ch) + ord(key[i]) - ord('a')
            if a > ord('z'):
                a -= 26
            encrypted += chr(a)
            i = (i + 1) % len(key)
        else:
            encrypted += ch
    print(encrypted)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM