简体   繁体   English

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

[英]String index out of range (Python)

I'm writing a program to encode, decode and crack with the Caesar Cipher. 我正在编写一个使用Caesar Cipher进行编码,解码和破解的程序。

I have this function that shifts the letters in a string along by a specified amount: 我有这个功能,可以将字符串中的字母移动指定的数量:

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

And I have this function to crack a ciphered string: 我有这个功能来破解一个加密的字符串:

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

However, after selecting 'y' to continue a few times, I get the following IndexError : 但是,在选择“ 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

Why am I getting this error and how can I fix it? 为什么会出现此错误,我该如何解决?

IndexError means that the index you are trying to access does not exist. IndexError表示您尝试访问的索引不存在。 In a string, that means you're trying to get a character from the string at a given point. 在字符串中,这意味着您试图在给定点从字符串中获取字符。 If that given point does not exist, then you will be trying to get a character that is not inside of the string. 如果给定的点不存在,那么您将尝试获取不在字符串内的字符。

"0123456"[7] tries to get the 7th character in the string, but that index does not exist so "IndexError" is raised. “ 0123456” [7]尝试获取字符串中的第7个字符,但是该索引不存在,因此引发了“ IndexError”。

All valid indexes on a string are less than the length of the string (when you do len(string)). 字符串上的所有有效索引均小于字符串的长度(执行len(string)时)。 In your case, alphabet[shiftedPos] raises IndexError because shiftedPos is greater than or equal to the length of the string "alphabet". 在您的情况下,Alphabet [shiftedPos]引发IndexError,因为shiftedPos大于或等于字符串“ alphabet”的长度。

To my understanding, what you want to do is loop back over the string when you go out of bounds like this. 据我了解,您想要做的就是像这样越界越过字符串。 "z" (character 25) gets incrimented by say 2 and becomes character 27. You want that to now become character 2 (letter "b") in this case. “ z”(字符25)增加2,成为字符27。在这种情况下,您希望现在变成字符2(字母“ b”)。 Hence, you should use modulo. 因此,您应该使用模。 replace "alphabet[shiftedPos]" with "alphabet[shiftedPos%len(alphabet)]" and I believe this will solve this problem. 用“ alphabet [shiftedPos%len(alphabet)]”替换“ alphabet [shiftedPos]”,我相信这将解决此问题。

Modulo, btw, divides a number by n and gives you the remainder. 顺便说一下,Modulo将数字除以n,然后得到余数。 Effectively, it will subtract n until the number is less than n (so it will always be in the range you want it to be in). 有效地,它将减去n直到数字小于n(因此它将始终在您希望其处于的范围内)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM