首页 > 解决方案 > 如何修复 IndexError?

问题描述

当我运行这个程序(它应该对进出凯撒密码的东西进行编码和解码)并选择解码选项时,我收到错误消息,指出字符串索引超出范围。谁能告诉我如何解决这个问题并告诉我为什么会这样?我输入的要解码的文本是 ibmmp,密钥是 1。谢谢。

alphabet = "abcdefghijklmnopqrstuvwxyz"
encdec = input("Would you like to encode or decode a message? ")
if encdec == "decode":
    keyyn = input("Do you know the key to your encoded text? (Y/N) ")
    if keyyn == "Y":
        plaintext = input("Please type in your text ")
        text = plaintext
        key = int(input("What is the key? "))
        for i in range(len(plaintext)):
            letter = plaintext[i]
            alphletter = alphabet.find(letter)
            alphletter = alphletter - key
            if alphletter < 0 or alphletter == 0:
                alphletter = alphletter + 26
                letter = alphabet[alphletter]
                plaintext = plaintext + letter
    else:
        letter = alphabet[alphletter]
        plaintext = plaintext + letter
    print(plaintext.strip(text))
else:
    print("This program is unable to decode a message without the key")

标签: pythonpython-3.x

解决方案


问题: ibmmp和1的关键

i工作,b给你一个错误。原因如下:

alphletter = alphabet.find(letter)              #  ==> 1
alphletter = alphletter - key                   #  ==> 0
if alphletter < 0 or alphletter == 0:           #  ==> True
    alphletter = alphletter + 26                    #   ==> 26 
letter = alphabet[alphletter]                   #  only has indexes from 0 to 25
plaintext = plaintext + letter                  #   ~~~~ crash ~~~~
# (also: indentation error for the last 2 lines)

您可以使用模运算符%来修复上溢/下溢:

alphletter = (alphletter - key) % 26   # for -1 : 25

您也可以使用if alphletter < 0:- 这不会处理多次环绕的键 (fe 210) 或否定键-22


一些优化

# create a mapping dictionary so we do not need index()
alph = "abcdefghijklmnopqrstuvwxyz"
len_alph = len(alph)

d = {c:i for i,c in enumerate(alph)}                  # mapping char to index
d.update( {v:k for k,v in d.items()} )                # mapping index to char
d.update( {c:i for i,c in enumerate(alph.upper())} )  # mapping CHAR to index

def encode(text,key):
    indexes = [d.get(c,"?") for c in text]      # only mapped things, others get ?
    # if ? use ? else lookup the correct replacement using % to make the index
    # wrap around if above/below the index into alph 
    return ''.join(d.get((i+key)%len_alph if i != "?" else "?","?") for i in indexes)

def decode(text,key):
    return encode(text,-key)


print(encode("tataaaa",5))

输出:

yfyffff

推荐阅读