Playfair密码实现:拆分明文为双字符组并处理相同字符的方案求教
Playfair密码明文拆分实现方案
提供两种兼顾简洁性和可读性的实现方式,均符合Playfair密码的明文分组规则:
1. 单轮迭代实现(推荐,性能与可读性最优)
仅需一次遍历即可完成分组、相同字符替换、末尾补位全流程,时间复杂度O(n):
def playfair_split(plaintext: str, fill_char: str = 'X') -> list[str]: # 按Playfair惯例统一转大写、J转I,可根据需求调整 plaintext = plaintext.upper().replace('J', 'I') groups = [] idx = 0 text_len = len(plaintext) while idx < text_len: first_char = plaintext[idx] # 剩余最后单个字符,补填充位 if idx == text_len - 1: groups.append(f"{first_char}{fill_char}") break second_char = plaintext[idx + 1] # 两个字符相同,替换第二个为填充字符,指针仅后移1位 if first_char == second_char: groups.append(f"{first_char}{fill_char}") idx += 1 else: groups.append(f"{first_char}{second_char}") idx += 2 return groups
默认填充字符按Playfair惯例使用X,可根据需求修改为Q等其他字符
2. 正则预处理实现(代码最简洁)
先通过正则批量替换所有相邻重复字符,再直接按固定长度拆分:
import re def playfair_split(plaintext: str, fill_char: str = 'X') -> list[str]: plaintext = plaintext.upper().replace('J', 'I') # 匹配相邻相同字符,中间插入填充字符 processed = re.sub(r'(.)\1', rf'\1{fill_char}\1', plaintext) # 总长度为奇数时末尾补填充 if len(processed) % 2: processed += fill_char # 直接按2字符长度拆分 return re.findall(r'.{2}', processed)
测试示例
输入明文HELLO:
- 匹配到连续字符
LL,替换为LXL,得到预处理结果HELXLO - 按2字符拆分得到
['HE', 'LX', 'LO'],完全符合规则要求
内容的提问来源于stack exchange,提问作者Solemnis
相关产品推荐
相关产品推荐

