按键流进行异或时的数组错误

时间:2013-01-02 18:43:53

标签: python xor

我正在尝试使用密钥流(key.bin)对文件(encoded_data.bin)进行异或,并且不断收到错误“数组索引超出范围”。密钥文件比数据文件长。任何帮助表示赞赏。我对python btw相当新 - 如果它已经不明显了。

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

3 个答案:

答案 0 :(得分:1)

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

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

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

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

for i in range(len(a2)):

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

答案 1 :(得分: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

答案 2 :(得分:0)

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

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

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

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

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