Python中if条件内直接索引列表触发IndexError,存变量则正常的原因
Python索引越界问题原因解析
两段用于CTF XOR解密的代码逻辑几乎一致,但一段运行时触发索引越界错误,另一段正常执行,具体情况如下:
报错的代码
import string arr1 = ['21', 'cf', '28', 'd6', '77', 'a3', '27', 'd2', '77', '2f', '85', '04', 'db', '35', '4d', '6f', 'a5', 'c3', 'd8', '64', '85', 'fe', '64', '6b', 'c0', '14', '5c', '13', '5f', '49', '0f', 'df', 'd8'] arr2 = ['73', '8a', '6c', '84', '32', 'e7', '75', '97', '33', '7d', 'c0', '40', '89', '70', '09', '3d', 'e0', '87', '8a', '21', 'c1', 'ac', '21', '2f', '92', '51', '18', '41', '1a', '0d', '5d', '9a', '9c'] txt = '' i = 0 while (i < 33): for a in string.printable: if ord(a) ^ int(arr1[i], 16) ^ int(arr2[i], 16) == 0: txt += a i += 1 print(txt)
报错信息
Traceback (most recent call last): File "d:\tempCodeRunnerFile.python", line 9, in <module> if ord(a) ^ int(arr1[i], 16) ^ int(arr2[i], 16) == 0: ~~~~^^^ IndexError: list index out of range
正常运行的代码
import string arr1 = ['21', 'cf', '28', 'd6', '77', 'a3', '27', 'd2', '77', '2f', '85', '04', 'db', '35', '4d', '6f', 'a5', 'c3', 'd8', '64', '85', 'fe', '64', '6b', 'c0', '14', '5c', '13', '5f', '49', '0f', 'df', 'd8'] arr2 = ['73', '8a', '6c', '84', '32', 'e7', '75', '97', '33', '7d', 'c0', '40', '89', '70', '09', '3d', 'e0', '87', '8a', '21', 'c1', 'ac', '21', '2f', '92', '51', '18', '41', '1a', '0d', '5d', '9a', '9c'] txt = '' i = 0 while (i < 33): x = arr1[i] y = arr2[i] for a in string.printable: if ord(a) ^ int(x, 16) ^ int(y, 16) == 0: txt += a i += 1 print(txt)
原因分析
问题核心是数组索引的求值时机和i的修改时机冲突:
- 报错代码中,
arr1[i]和arr2[i]是每次执行if判断时才会去数组中取值。当找到匹配的字符后,i会立刻加1,但内层for循环并未结束,后续迭代中,if条件会使用已经递增后的i去访问数组。 - 当
i递增到33时,外层while循环的条件i < 33已经不满足,但内层for循环仍在继续执行,此时访问arr1[33]就会触发索引越界——两个数组的长度均为33,合法索引范围是0到32。 - 正常运行的代码中,进入
for循环前就将当前i对应的数组元素值存入x和y,后续for循环迭代时,无论i如何变化,都是使用之前保存的x和y进行计算,不会再去访问数组的新索引,因此不会触发越界错误。
内容的提问来源于stack exchange,提问作者FlaB
相关产品推荐
相关产品推荐

