字符串索引超出范围(Python)

yeum 发布于 2019-11-08 encryption 最后更新 2019-11-08 22:59 9 浏览

我正在编写一个程序来编码,解码和破解凯撒密码。 我有这个函数将字符串中的字母移动一个指定的数量:

def shift(data, shifter):
    alphabet = "abcdefghijklmnopqrstuvwxyz"
    data = list(data)
    counter = 0  #  we will use this to modify the list while we iterate over it
    for letter in data:
        letter = letter.lower()
        if letter not in alphabet:
            counter += 1
            continue
        lPos = alphabet.find(letter)
        if shifter >= 0:
            shiftedPos = lPos + (0 - shifter)
        else:
            shiftedPos = lPos + abs(shifter)
        if shiftedPos >= len(alphabet) - 1: shiftedPos -= len(alphabet)
        data[counter] = alphabet[shiftedPos]  #  update the letter
        counter += 1  # advance
    data = ''.join(data)  # make it into a string again
    return data
我有这个函数来破解一个加密的字符串:
def crack(decryptor=None, tries=None):
    if decryptor is None and tries is None:
        task = getValidInput("Get data from a [f]ile or [s]tdin?  >", "Please give either 'f' or 's'.", 'f', 's')
        if task == "f":  # it's a file
            dataFile = getValidFile()  # get an open file object
            data = dataFile.read()  # get the data from the text file. hopefully it's ascii text!
        elif task == "s":  # we need to get data from stdin
            data = input("Enter data to crack  >")
        tries = getValidInt("Enter tries per sweep  >")
    else:
        data = decryptor
retry = True
    shifter = 0
    while retry:
        for i in range(0, tries):
            oput = "Try " + str(i) + ": "
            posData = shift(data, shifter)
            negData = shift(data, 0 - shifter)
            # semitry 1 - positive
            oput += posData + ", "
            # semitry 2 - negative
            negData = ''.join(negData)  # make it into a string again
            oput += negData
print(oput)
shifter += 1
doRetry = getValidInput("Keep trying (y/n)? > ", "Invalid!", 'y', 'n')
        if doRetry == 'n': retry = False
但是,选择'y'继续几次后,我会得到以下IndexError
Traceback (most recent call last):
  File "CeaserCypher.py", line 152, in <module>
    crack()
  File "CeaserCypher.py", line 131, in crack
    negData = shift(data, 0 - shifter)
  File "CeaserCypher.py", line 60, in shift
    print(alphabet[shiftedPos])
IndexError: string index out of range
为什么我得到这个错误,我该如何解决它?
已邀请:

rsaepe

赞同来自:

IndexError意味着您尝试访问的索引不存在。在字符串中,这意味着您正在尝试从给定点的字符串中获取字符。如果该给定点不存在,那么您将尝试获取不在字符串内的字符。 “0123456”[7]尝试获取字符串中的第7个字符,但该索引不存在,因此引发“IndexError”。 字符串上的所有有效索引都小于字符串的长度(当您执行len(string)时)。在您的情况下,alphabet [shiftedPos]会引发IndexError,因为shiftedPos大于或等于字符串“alphabet”的长度。 根据我的理解,当你走出这样的界限时,你想要做的是循环回到字符串。 “z”(字符25)被2说出并变成了字符27.在这种情况下,你想要现在成为字符2(字母“b”)。因此,你应该使用modulo。将“alphabet [shiftedPos]”替换为“alphabet [shiftedPos%len(alphabet)]”,我相信这将解决这个问题。 Modulo,顺便说一下,将数字除以n,然后给出余数。实际上,它会减去n,直到数字小于n(所以它总是在你想要的范围内)。