两个多字节二进制数据变量之间的最快按位xor

Nik*_*lov 12 python bitwise-operators multibyte

实现以下逻辑的最快方法是什么:

def xor(data, key):
    l = len(key)

    buff = ""
    for i in range(0, len(data)):
        buff += chr(ord(data[i]) ^ ord(key[i % l]))
    return buff
Run Code Online (Sandbox Code Playgroud)

在我的情况下,密钥是20字节的sha1摘要,数据是20字节和几(1,2,3)兆字节之间的一些二进制数据

更新:

好,朋友们.这是一个快3.5倍的实现,它将数据和密钥分成4个,2个或1个字节(在我的情况下,大多数情况下它是4字节长整数):

def xor(data, key):
    index = len(data) % 4
    size = (4, 1, 2, 1)[index]
    type = ('L', 'B', 'H', 'B')[index]
    key_len = len(key)/size
    data_len = len(data)/size
    key_fmt = "<" + str(key_len) + type;
    data_fmt = "<" + str(data_len) + type;

    key_list = struct.unpack(key_fmt, key)
    data_list = struct.unpack(data_fmt, data)

    result = []
    for i in range(data_len):
        result.append (key_list[i % key_len] ^ data_list[i])

    return struct.pack(data_fmt, *result)
Run Code Online (Sandbox Code Playgroud)

使用大量内存,但就我而言,这并不是什么大问题.

任何想法如何提高速度几次?:-)

最终更新:

好的,好的... numpy完成了这项工作.这真是太快了:

def xor(data, key):
    import numpy, math

    # key multiplication in order to match the data length
    key = (key*int(math.ceil(float(len(data))/float(len(key)))))[:len(data)]

    # Select the type size in bytes       
    for i in (8,4,2,1):
        if not len(data) % i: break

    if i == 8: dt = numpy.dtype('<Q8');
    elif i == 4: dt = numpy.dtype('<L4');
    elif i == 2: dt = numpy.dtype('<H2');
    else: dt = numpy.dtype('B');

    return numpy.bitwise_xor(numpy.fromstring(key, dtype=dt), numpy.fromstring(data, dtype=dt)).tostring()
Run Code Online (Sandbox Code Playgroud)

初始实现需要8分50秒来处理一个千兆字节,第二个 - 大约2分30秒,最后一个只需要...... 0分10秒.

感谢任何贡献想法和代码的人.你们太棒了!

orl*_*rlp -1

您所拥有的速度已经与 Python 中所能达到的速度一样快了。

如果您确实需要更快,请用 C 实现。