Проблема в том, что вы используете одну и ту же переменную счетчика i
, чтобы отметить свое место в двух разных строках: message
и long_key
. Каждый раз, когда вы встречаетесь с небуквенным символом в message
, вы переходите к следующему символу, но вы также переходите к следующему символу в long_key
, а это не то, что вы хотите делать.
Если вы просто используете i
для подсчета символов в long_key
, проблема исчезнет. Например:
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))
Вы также можете немного упростить свой код. Вы можете использовать функцию ord
для преобразования значений ASCII в целые числа и оператор модуля для циклического перебора значений key
без необходимости расширять его до размера входного сообщения.
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)