栅栏密码(Rail Fence Cipher)编码解码函数实现及问题修复
栅栏密码编码/解码函数修正方案
原代码问题分析
轨道索引序列生成错误
原fence函数中rails = range(numrails - 1) and range(numrails - 1, 0, -1)的写法不符合Python逻辑:and运算符会返回最后一个真值表达式,因此当numrails≥2时,rails实际仅为range(numrails-1, 0, -1),导致字符的轨道分配完全偏离栅栏密码的规则(正确顺序应为0→1→2→1→0→1→2...)。解码逻辑错误
原解码函数中string[pos.index(n)]的方式逻辑混乱:pos.index(n)会返回n在列表中首次出现的位置,但这无法正确映射编码后的字符到原位置,正确的解码需要先拆分编码字符串到对应轨道,再按原顺序读取。
正确实现代码
编码函数
def encode_rail_fence_cipher(string, n): if n == 1 or not string: return string # 初始化n个轨道 rails = [[] for _ in range(n)] current_rail = 0 direction = 1 # 1表示向下移动,-1表示向上移动 for char in string: rails[current_rail].append(char) current_rail += direction # 到达顶部或底部轨道时反转方向 if current_rail == 0 or current_rail == n - 1: direction *= -1 # 拼接所有轨道的字符 return ''.join(''.join(rail) for rail in rails)
解码函数
def decode_rail_fence_cipher(string, n): if n == 1 or not string: return string str_len = len(string) # 先计算每个轨道应分配的字符数量 rail_lengths = [0] * n current_rail = 0 direction = 1 for _ in range(str_len): rail_lengths[current_rail] += 1 current_rail += direction if current_rail == 0 or current_rail == n - 1: direction *= -1 # 将编码后的字符串拆分到对应轨道 rails = [] start_idx = 0 for length in rail_lengths: rails.append(list(string[start_idx:start_idx + length])) start_idx += length # 按原顺序从轨道中取出字符 result = [] current_rail = 0 direction = 1 for _ in range(str_len): result.append(rails[current_rail].pop(0)) current_rail += direction if current_rail == 0 or current_rail == n - 1: direction *= -1 return ''.join(result)
测试验证
输入测试字符串"WEAREDISCOVEREDFLEEATONCE",轨道数3:
- 编码结果:
WECRLTEERDSOEEFEAOCAIVDEN(与预期一致) - 解码该编码结果,可还原出原字符串。
内容的提问来源于stack exchange,提问作者OrigamiDarknessDragon
相关产品推荐
相关产品推荐

