【发布时间】:2011-08-09 17:35:32
【问题描述】:
以下逻辑最快的实现方式是什么:
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
在我的例子中,key 是 20 字节的 sha1 摘要,data 是一些介于 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)
使用大量内存,但在我的情况下,这没什么大不了的。
任何想法如何提高速度几次? :-)
最终更新:
好的,好的... 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()
初始实现需要 8 分 50 秒来处理一个千兆字节,第二个 - 大约 2 分 30 秒,最后一个只是.... 0 分 10 秒。
感谢任何贡献想法和代码的人。你们是好人!
【问题讨论】:
-
“最快”?好吧,运行时速度开销最低的方式是 C(或 Cython,用于心脏弱者)扩展。
-
创建一个
key:ord(key)+val:ord(val)(来自set(key) | set(data))的字典来保存许多ord调用?然后使用列表推导而不是字符串连接? -
这里有相当详细的看这个问题:stackoverflow.com/questions/2119761/…
-
当异或一个 16M 的字符串时,我刚刚发布的那个占用了你当前最快的 42% 的时间,并且显着减少了内存。它也不依赖于 numpy 或内联汇编。
-
另外,我不知道你打算用这个做什么,但这是一种完全可怕的加密方法。
标签: python bitwise-operators multibyte