如何将hex文件读入numpy数组

时间:2013-05-30 18:08:34

标签: python numpy

我想加载以下具有

的十六进制文件

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亿个普通文本。

谢谢,如果您有任何问题,请告诉我

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>