Python实现Caesar Cipher解密函数报字符串索引越界错误
Python凯撒密码解密报字符串索引越界问题修复
问题现象
- 编写简易Caesar Cipher(凯撒密码)程序时,加密函数运行正常,调用解密函数触发
string index out of range(字符串索引超出范围)报错 - 问题代码如下:
import random symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!?@#$%^&*()' " def encrypt_symbols(message, key): encrypted = '' index = 0 for letter in message: index = symbols.find(letter) + key if index > len(symbols): index = index - (len(symbols) + 1) encrypted = encrypted + symbols[index] return encrypted def decrypt(message, key): decrypted = '' index = 0 for letter in message: index = symbols.find(letter) - key if index < len(symbols): index = index + len(symbols) decrypted = decrypted + symbols[index] return decrypted test = "Wow! This works well, don't you think so?" key = random.randrange(1, len(symbols)) secret_message = encrypt_symbols(test, key) print(encrypt_symbols(test, key)) print(decrypt(secret_message, key))
错误原因排查
一共3个核心问题:
- 字符集缺漏:定义的
symbols字符集没有包含测试明文里的英文逗号,和问号?,symbols.find()匹配不到这两个字符时会返回-1,参与索引计算直接生成无效下标。 - 加密边界判断错误:字符串有效索引范围是
0到len(symbols)-1,原逻辑只判断index > len(symbols)才做回绕,漏掉了index == len(symbols)的越界场景,回绕计算的偏移值也不对。 - 解密逻辑完全写反:减key后可能出现负数索引,原逻辑判断
index < len(symbols)就加字符集长度,等于几乎所有合法索引都会被加上长度,直接超出有效索引范围。
修复方案
- 补全
symbols字符集缺失的逗号、问号,和测试用例的字符范围对齐 - 用*取模运算
%*替代手动边界判断,自动处理索引循环回绕,避免手写判断的逻辑错误 - 增加字符不存在的兼容分支,遇到不在字符集里的字符直接保留,避免
find()返回-1导致的计算异常 - 去掉重复的加密调用,直接复用已生成的密文变量
修复后可运行代码:
import random # 补全缺失的逗号、问号,覆盖测试用例所有字符 symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!?@#$%^&*()',? " def encrypt_symbols(message, key): encrypted = '' symbols_len = len(symbols) for letter in message: pos = symbols.find(letter) # 不在字符集内的字符直接保留 if pos == -1: encrypted += letter continue # 取模自动处理循环回绕 index = (pos + key) % symbols_len encrypted += symbols[index] return encrypted def decrypt(message, key): decrypted = '' symbols_len = len(symbols) for letter in message: pos = symbols.find(letter) if pos == -1: decrypted += letter continue # 取模自动处理负数索引的回绕 index = (pos - key) % symbols_len decrypted += symbols[index] return decrypted test = "Wow! This works well, don't you think so?" key = random.randrange(1, len(symbols)) secret_message = encrypt_symbols(test, key) print("加密结果:", secret_message) print("解密结果:", decrypt(secret_message, key))
注:取模运算处理环形索引是移位类密码的通用写法,比手动写大小判断简洁且容错性高,不需要单独处理上越界、下越界的分支。
内容的提问来源于stack exchange,提问作者DDowns
相关产品推荐
相关产品推荐

