You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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个核心问题:

  1. 字符集缺漏:定义的symbols字符集没有包含测试明文里的英文逗号,和问号?,symbols.find()匹配不到这两个字符时会返回-1,参与索引计算直接生成无效下标。
  2. 加密边界判断错误:字符串有效索引范围是0到len(symbols)-1,原逻辑只判断index > len(symbols)才做回绕,漏掉了index == len(symbols)的越界场景,回绕计算的偏移值也不对。
  3. 解密逻辑完全写反:减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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:45:32