我想加载以下具有
的十六进制文件 1)在第一行初始化值(IV),
2)第二行的加密键,
3)第三行的明文数量,和
4)密码块链接(CBC)模式下AES加密的实际纯文本
进入numpy数组。
6bce1cb8d64153f82570751b6653c943
b15a65475a91774a45106fbc28f0df70
10
f493befb2dcad5118d523a4a4bf4a504
54fc4e0a82ae8dc56cc7befc9994b79d
878d287647b457fd95d40691b6e0c8ab
dc0adc16665eb96a15d3257752ae67dc
8cda3b8f23d38e9240b9a89587f69970
e06301763146c1bac24619e61015f481
c19def2f12e5707d89539e18ad104937
048d734a1a36d4346edc7ceda07ff171
5e621ce0a570478c1c2ec3e557ca3e0d
e55c57b119ff922b7f87db0ead2006cd
如果文件的统一性困扰您,您可以忽略第三行,该第三行说明要加密的纯文本的数量。除第三行之外的所有行都是128位十六进制条目
我们的想法是将此文件加载到numpy数组中,然后有效地进行AES加密。
如何将其加载到numpy数组中,然后使用来自Crypto.Cipher的AES对此文件和类似文件进行AES加密。我有这种格式的文件,有1亿个普通文本。
谢谢,如果您有任何问题,请告诉我
答案 0 :(得分:4)
我假设您要取消数据的重新启动,并将生成的字节串存储为固定长度的字符串而不是object
。 (你不能将它们存储为某种int128类型,因为numpy没有这种类型。)
为了避免将3.2GB的文本读入内存,并使用大致相同的数量预处理到所需的格式,您可能希望使用fromiter
,所以:
with open(myfile) as f:
iv = binascii.unhexlify(f.readline().strip())
key = binascii.unhexlify(f.readline().strip())
count = int(f.readline())
a = np.fromiter((binascii.unhexlify(line.strip()) for line in f), dtype='|S16')
如果你有10GB的RAM备用(粗略的猜测),可能以array
的{{1}}读取整个内容更快,然后转换它两次......但我对此表示怀疑。
至于这是否会有所帮助......你可能会得到一些好处,因为AES-16字节可能足够快,以至于迭代的成本是显而易见的。让我们测试一下吧。
使用64位Mac Python 2.7.2,我通过重复复制您的示例创建了一个包含100000个S16的数组。然后:
object
所以,这几乎节省了25%。还不错。
当然,数组构建所需的时间比首先将迭代器保留在迭代器中要长 - 但即使考虑到这一点,仍然有9%的性能提升。在您的用例中,以9%的速度交换1.6GB可能是合理的。
请记住,我只是在预先存在的100K列表中构建一个100K对象的数组; 100M对象读取磁盘,I / O可能会成为一个严重的因素,迭代处理(允许您将CPU成本与磁盘等待交错)很可能会做得更好。
换句话说,您需要使用自己的实际数据和方案进行测试。但你已经知道了。
对于更广泛的实现,使用简单的性能测试支架,请参阅this pastebin。
您可能想尝试合并不同的方法。例如,您可以使用In [514]: %timeit [aes.encrypt(x) for x in a]
10 loops, best of 3: 166 ms per loop
In [515]: %timeit np.vectorize(aes.encrypt)(a)
10 loops, best of 3: 126 ms per loop
中的grouper
配方一次将事物批量处理为32K plaintexts,然后使用numpy处理每个批处理,以充分利用两者。然后itertools
进行numpy处理,以获得最佳效果3.或者,将一个大的pool.imap
数组放入共享内存中,并使每个多处理任务处理该数组的一部分。 / p>