Vigenere密码实现:关键词过短时如何循环从头取密钥
修复Vigenere密码的密钥自动循环逻辑
问题原因
原代码用zip()同步遍历明文和密钥时,会在两个序列中较短的一个遍历完成后直接终止,因此当密钥长度小于明文时,明文末尾的字符不会被加密,不符合Vigenere密码密钥循环复用的规则。
解决方法
最简洁的实现是使用标准库itertools.cycle包装密钥,该方法会在密钥遍历到末尾时自动从头开始循环取值,不需要手动拼接长密钥或者计算索引偏移,只需要改动一行代码即可:
import string from itertools import cycle def vigenere_cipher(msg, shift): encrypted = '' # cycle(shift)会无限循环迭代密钥内容 for i, j in zip(msg, cycle(shift)): new_index = (string.ascii_uppercase.index(i) + string.ascii_uppercase.index(j)) % 26 encrypted += string.ascii_uppercase[new_index] return encrypted print(vigenere_cipher('PYTHON', 'MATH'))
效果验证
用长度为4的密钥MATH加密长度为6的明文PYTHON时,密钥会自动循环补全为MATHMA和明文逐位匹配:
- 第1位P + 密钥M → B
- 第2位Y + 密钥A → Y
- 第3位T + 密钥T → M
- 第4位H + 密钥H → O
- 第5位O + 循环到的密钥M → A
- 第6位N + 循环到的密钥A → N
最终运行输出为BYMOAN,完全符合加密规则。
无依赖替代方案:如果不想导入itertools,可以在遍历明文时通过索引取模获取对应密钥字符,核心逻辑为
for idx, i in enumerate(msg): j = shift[idx % len(shift)],但代码简洁度不如使用cycle的方案。
内容的提问来源于stack exchange,提问作者MrTiredVeryTired
相关产品推荐
相关产品推荐

