0

我正在尝试使用密钥流(key.bin)对文件(encoded_data.bin)进行异或,并不断收到错误“数组索引超出范围”。密钥文件比数据文件长。任何帮助表示赞赏。顺便说一句,我对 python 还很陌生——如果它还不明显的话。

import array
k=open("key.bin", "rb")
s=open("encoded_data.bin", "rb")
t=k.read()
r=s.read()
a1 = array.array('B', (t))
a2 = array.array('B', (r))
for i in range(len(a1)):
   a1[i] ^= a2[i]

   print a1.tostring()

   k.close
   s.close
4

3 回答 3

1

发生这种情况是因为密钥文件更长,正如您所说,并且您正在循环密钥文件中的每个字节:

for i in range(len(a1)):
    a1[i] ^= a2[i]

一旦i等于,len(a2)当您尝试 fetch 时,您将获得此异常a2[i],因为i超出了数组的范围。

根据您的问题,目前尚不清楚正确的解决方案是什么,但是如果您知道数据将始终小于密钥,则只需使用数据的长度即可:

for i in range(len(a2)):

如果您的目标是在数据大于密钥时重复密钥,则解决方案将涉及更多。

于 2013-01-02T18:46:45.447 回答
0

如果您的数据比您的密钥长(当然,这是一个主要的加密禁忌!),这样的解决方案将适用于您的情况:

def xorloop(l, xors):
    return [l[i] ^ xors[i % len(xors)] for i in xrange(len(l))]

它需要可异或的值的迭代,如下所示:

>>> xorloop([1, 2, 3, 4, 5], [6, 7, 8])
[7, 5, 11, 2, 2]

array您可以使用示例中的方法轻松地将其调整为字符串。

于 2013-01-02T18:55:27.340 回答
0

您实际上可以使用内置zip函数。它允许您一次循环两个迭代,这适合您的情况。

plaintext = []
for key_byte, ciphertext_byte in zip(a1, a2):
    plaintext.append(chr(ord(key_byte) ^ ord(ciphertext_byte)))

print ''.join(plaintext)

如果密文中有多余的字节,它们将被忽略。如果密钥中有额外的字节,它们将不会被使用。


我认为您正在实施一次性垫。让我建议你在这里使用bytearrays

key = byterray(k.read())
ciphertext = bytearray(s.read())
plaintext = bytearray()

for key_byte, ciphertext_byte in zip(key, ciphertext):
    plaintext.append(key_byte ^ ciphertext_byte)

print plaintext
于 2013-01-02T18:49:38.933 回答