如何修复IndexError?

时间:2018-11-27 17:56:24

标签: python python-3.x

当我运行该程序(应该对凯撒密码进行编码和解码)并选择解码选项时,出现错误消息,提示字符串索引超出范围。谁能告诉我如何解决这个问题,并告诉我为什么会这样?我输入的要解码的文本是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")

1 个答案:

答案 0 :(得分:1)

问题: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:-这将无法处理多次环绕的键(例如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