我正在编写一个用Caesar Cipher进行编码,解码和破解的程序。
我有这个函数可以将字符串中的字母移动指定的数量:
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
为什么我会收到此错误以及如何解决?
答案 0 :(得分:0)
IndexError意味着您尝试访问的索引不存在。在字符串中,这意味着您正在尝试从给定点的字符串中获取字符。如果该给定点不存在,那么您将尝试获取不在字符串内的字符。
&#34; 0123456&#34; [7]尝试获取字符串中的第7个字符,但该索引不存在,因此&#34; IndexError&#34;被提出来了。
字符串上的所有有效索引都小于字符串的长度(当你执行len(string)时)。在您的情况下,alphabet [shiftedPos]会引发IndexError,因为shiftedPos大于或等于字符串&#34; alphabet&#34;的长度。
根据我的理解,当你走出这样的界限时,你要做的是循环回字符串。 &#34; Z&#34; (字符25)被说出2并且成为字符27.在这种情况下,你想要现在成为字符2(字母&#34; b&#34;)。因此,你应该使用modulo。替换&#34;字母表[shiftedPos]&#34;用&#34;字母表[shiftedPos%len(alphabet)]&#34;而且我相信这会解决这个问题。
Modulo,顺便说一下,用n除以数字,给出余数。实际上,它会减去n,直到数字小于n(所以它总是在你想要的范围内)。