Python解决Vigenère编码挑战 适配密码迭代移位的列表推导式逻辑问题
问题核心原因
你现有代码的问题如下:
- 未接入密码迭代逻辑,固定给所有字母加1移位,恰好和你密码
ab的第二位移1规则匹配,才会出现隔一个字符正确的情况 - 你定义的
alphabet大写段漏了字符W,会导致大写W查找失败 - 移位未做模运算,超出字母表长度时会触发索引溢出错误
修正方案
我们用itertools.cycle实现密码的循环迭代,先把密码字符转成对应的移位值,再逐字符编码:
from itertools import cycle message = "Entwicklerhelden are having fun while coding" desired_output = "Eotxidkmeshfleeo brf iawiog fvn wiime cpdjnh" # 拆分大小写字母表单独处理,避免索引混乱 lower_alphabet = "abcdefghijklmnopqrstuvwxyz" upper_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" password = "ab" # 把密码转成循环迭代的移位值:a对应移0,b对应移1,以此类推 shift_cycle = cycle([lower_alphabet.index(c) for c in password]) encoded_list = [] for char in message: if char in lower_alphabet: # 小写字符编码 idx = lower_alphabet.index(char) shift = next(shift_cycle) encoded_list.append(lower_alphabet[(idx + shift) % 26]) elif char in upper_alphabet: # 大写字符编码 idx = upper_alphabet.index(char) shift = next(shift_cycle) encoded_list.append(upper_alphabet[(idx + shift) % 26]) else: # 非字母字符直接保留,不消耗密码移位值 encoded_list.append(char) result = "".join(encoded_list) # 验证输出 print(result == desired_output) # 输出True print(result)
逻辑说明
- 用
cycle迭代器实现密码用完自动从头循环的需求,每次处理字母时调用next(shift_cycle)获取当前移位值 - 非字母字符(空格、标点等)不消耗密码移位值,直接保留
- 移位后加
%26模运算,避免索引越界 - 拆分大小写字母表单独处理,不需要维护超长的大小写混合字母表,也避免大小写索引错位问题
如果你偏好列表推导式的写法,可以用enumerate配合索引取模获取移位值:
lower_alphabet = "abcdefghijklmnopqrstuvwxyz" upper_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" password = "ab" shifts = [lower_alphabet.index(c) for c in password] password_len = len(shifts) non_alpha_count = 0 encoded_list = [] for i, char in enumerate(message): if not char.isalpha(): encoded_list.append(char) non_alpha_count += 1 else: shift = shifts[(i - non_alpha_count) % password_len] if char.islower(): encoded_list.append(lower_alphabet[(lower_alphabet.index(char) + shift) % 26]) else: encoded_list.append(upper_alphabet[(upper_alphabet.index(char) + shift) % 26])
内容的提问来源于stack exchange,提问作者KWunsch
相关产品推荐
相关产品推荐

