带双参数的Caesar Cipher编码正常但解码失效,求排查
凯撒密码解码功能失效排查
问题描述
实现了一个带参数m和n的凯撒密码,移位规则如下:
- 首个字符(char1)移位(n+m)位;
- 第二个字符(char2)移位n+pos_char1位(pos_char1为char1在a-z字母表中的索引),后续字符以此类推;
- 仅对小写字母生效,其余字符保持不变。
编码功能正常,例如输入"aaaaaa"、n=2、m=2时输出"egikmo"符合预期,但解码功能无法还原原数据:以"egikmo"作为解码输入,无法得到原输入"aaaaaa"。
编码代码
def encode_cipher(n, m, message): result = "" p = m # Initialize p with the additional step shift 'm' for char in message: if char.islower(): # Determine the shift value for the current lowercase character shift = n + p # Adjust the shift to keep it within the range [0, 25] shift = shift % 26 new_char = chr(((ord(char) - ord('a') + shift) % 26) + ord('a')) result += new_char # Update the value of p for the next character p = ((ord(new_char) - ord('a')) % 26) else: # If the character is not a lowercase letter, leave it unchanged result += char return result # Example usage for encoding message = "aaaaaa" n = 2 m = 2 encode_cipher(n, m, message)
解码代码(原错误版本)
def decode_cipher(n, m, message): result = "" p = m # Initialize p for char in message: if char.islower(): shift = n + p shift = shift % 26 new_char = chr(((ord(char) - ord('a') - shift) % 26) + ord('a')) result += new_char # Update the value of p for the next character p = ((ord(new_char) - ord('a')) % 26) else: result += char return result # Example message = "egikmo" # Using output from encode function above. n = 2 m = 2 decode_cipher(n, m, message)
失效原因分析
解码函数的核心错误在于p的更新逻辑:
- 编码过程中,每处理完一个字符后,
p会被更新为该字符编码后的索引,这个值会作为下一个字符移位计算的一部分。 - 原解码函数中,错误地将
p更新为解码后的原字符索引,导致后续字符的移位计算完全偏离编码时的逻辑,无法正确逆推原数据。
举个具体例子:
编码第一个字符a时,移位为2+2=4,得到e,p被设为e的索引4;
解码第一个字符e时,正确逆推得到a,但原解码函数将p设为a的索引0,导致第二个字符的移位计算为2+0=2,而不是编码时的2+4=6,最终无法得到正确的原字符。
修正后的解码函数
将p的更新逻辑改为使用当前输入的编码字符的索引,与编码逻辑对齐:
def decode_cipher(n, m, message): result = "" p = m # 初始值与编码一致 for char in message: if char.islower(): shift = n + p shift = shift % 26 # 逆推原字符 new_char = chr(((ord(char) - ord('a') - shift) % 26) + ord('a')) result += new_char # 更新p为当前输入编码字符的索引,匹配编码时的逻辑 p = ((ord(char) - ord('a')) % 26) else: result += char return result
测试验证:输入"egikmo"、n=2、m=2,将返回原输入"aaaaaa"。
内容的提问来源于stack exchange,提问作者Albert Lutakome
相关产品推荐
相关产品推荐

