Python维吉尼亚密码输出与正确答案不符
我写了一些代码来解码维吉尼亚密码。但是它总是输出错误的解码信息。
这是我的代码:
alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
v_message= "txm srom vkda gl lzlgzr qpdb? fepb ejac! ubr imn tapludwy mhfbz cza ruxzal wg zztylktoikqq!"
keyword = "friends"
def vigenere_cipher(message, keyword):
decoded = []
for i in range(len(message)):
char = message[i]
if char.isalpha():
char_index = alphabet.index(char)
key_index = alphabet.index(keyword[i % len(keyword)])
letter_index = (char_index - key_index) % len(alphabet)
decoded.append(alphabet[letter_index])
else:
decoded.append(char)
return "".join(decoded)
print(vigenere_cipher(v_message, keyword))
它给我的输出是:
oge fowh ngqx bu hmioua mcaj? xacy zssy! cwa ezk ojhhhaet edsyh lrw ocsish to irplisoxagdn!
我不知道哪里出错了。有没有人能帮我修复一下我的代码呢?
我也问过chatGPT,但它找不到实际的错误。
2 个回答
1
Vigenère编码和解码之间唯一的区别就是一小段数学运算。因此,这两项工作可以在一个函数中完成,只需要传入一个可调用的对象来处理这个差异。
from string import ascii_lowercase
from itertools import cycle
from operator import add, sub
from collections.abc import Callable
AMAP = {c: o for o, c in enumerate(ascii_lowercase)}
def crypto(msg: str, key: str, func: Callable) -> str:
assert msg.lower() == msg and key.lower() == key
rv = ""
k = cycle(key)
for c in msg:
if c in AMAP:
a = AMAP[c]
b = AMAP[next(k)]
p = func(a, b)
rv += ascii_lowercase[p % 26]
else:
rv += c
return rv
def encrypt(msg: str, key: str) -> str:
return crypto(msg, key, add)
def decrypt(msg: str, key: str) -> str:
return crypto(msg, key, sub)
KEY = "friends"
msg = "you were able to decode this? nice work! you are becoming quite the expert at cryptography!"
enc = encrypt(msg, KEY)
print(enc)
print(decrypt(enc, KEY))
输出:
dfc aruw fsti gr vjtwhr wznj? vmph otis! cbx swv jipreneo uhllj kpi rahjib eg fjdgbstusuyg!
you were able to decode this? nice work! you are becoming quite the expert at cryptography!
注意:
This code only works for lowercase ASCII
4
你现在是把字母往字母表后面移,但其实应该往前面移。这跟Vigenere密码是相反的,评论里也提到了。所以把
letter_index = (char_index - key_index) % len(alphabet)
改成letter_index = (char_index + key_index) % len(alphabet)
。对于空格,
i
不应该增加。
def vigenere_cipher(message, keyword):
decoded = []
i = 0
for char in message:
if char.isalpha():
char_index = alphabet.index(char)
key_index = alphabet.index(keyword[i % len(keyword)])
letter_index = (char_index + key_index) % len(alphabet)
decoded.append(alphabet[letter_index])
i += 1
else:
decoded.append(char)
return "".join(decoded)
这段代码会输出:
你居然能解码这个?真不错!你在密码学方面越来越有经验了!