问题
In my code for vigenere cipher I use cycle from itertools to cycle through the key word. This works great until I use spaces in the message as it encrypts the space therefore making the encryption wrong. Here is the code.
message = input('enter message: ')
keyword = input('enter keyword: ')
def chr_to_int(char):
return 0 if char == 'z' else ord(char)-96
def int_to_chr(integer):
return 'z' if integer == 0 else chr(integer+96)
def add_chars(a, b):
return int_to_chr(( chr_to_int(a) + chr_to_int(b)) % 26 )
def vigenere(message, keyword):
keystream = cycle(keyword)
new = ''
for msg, key in zip(message, keystream):
if msg == ' ':
new += ' '
else:
new += add_chars(msg, key)
return new
new = vigenere(message, keyword)
print('your encrypted message is: ',new)
I think a solution to this problem would be to cycle through the space the same length of the message so it will carry on to the next letter as if the space wasn't there. I do not know how to go about how to do this .
example:
message: vignere cipher keyword: qwerty
encrypted mesasge (what it should be): mflahdib hajgvo
回答1:
since cycle
returns an iterable, you could instead use next
instead of zip so that it only calls for the next char when asked:
>>> def vigenere(message, keyword):
keystream = cycle(keyword)
new = ''
for msg in message:
if msg == ' ':
new += ' '
else:
new += add_chars(msg, next(keystream))
return new
>>> new = vigenere('computing is fun', 'gcse')
>>> new
'jrfubwbsn ll kbq'
EDIT: per OP request, uses zip and offset variable
>>> def vigenere(message, keyword):
keystream = cycle(keyword)
new = ''
offset = 0
for msg, key in zip(message,keystream):
if msg == ' ':
new += ' '
offset += 1
else:
new += add_chars(msg, keyword[keyword.index(key)-offset])
return new
>>> new = vigenere('computing is fun', 'gcse')
>>> new
'jrfubwbsn ll kbq'
来源:https://stackoverflow.com/questions/33442220/itertools-cycle-in-vigenere-cipher-causing-problems-with-spaces-python