创建随机二进制文件

时间:2013-01-11 10:18:13

标签: python random

我正在尝试使用python来创建随机二进制文件。这就是我已经拥有的:

f = open(filename,'wb')
for i in xrange(size_kb):
    for ii in xrange(1024/4):
        f.write(struct.pack("=I",random.randint(0,sys.maxint*2+1)))

f.close()

但它非常慢(我的3.9GHz SSD磁盘机上size_kb = 1024,为0.82秒)。一个很大的瓶颈似乎是随机int生成(用0替换randint()会将运行时间从0.82s减少到0.14s)。

现在我知道有更有效的方法可以创建随机数据文件(即dd if = / dev / urandom)但是我想为了好奇而想出来......有一种明显的方法来改善这个?

2 个答案:

答案 0 :(得分:39)

恕我直言 - 以下内容完全是多余的:

f.write(struct.pack("=I",random.randint(0,sys.maxint*2+1)))

绝对不需要使用struct.pack,只需执行以下操作:

import os

with open('output_file', 'wb') as fout:
    fout.write(os.urandom(1024)) # replace 1024 with size_kb if not unreasonably large

然后,如果您需要重新使用该文件来读取整数,那么struct.unpack就可以了。

  

(我的用例是为单元测试生成一个文件,所以我只需要一个   文件与其他生成的文件不同。)

另一种选择是只将UUID4写入文件,但由于我不知道确切的用例,我不确定它是否可行。

答案 1 :(得分:3)

您应该完全编写的python代码取决于您打算使用随机二进制文件的方式。如果你只需要一个“相当好”的随机性用于多种目的,那么Jon Clements的代码可能是最好的。

但是,至少在Linux OS上,os.urandom依赖于/ dev / urandom,它在Linux内核(drivers / char / random.c)中描述如下:

  

/ dev / urandom设备[...]将返回尽可能多的字节数   请求。随着越来越多的随机字节被请求而没有给出   熵池充电的时间,这将导致随机   数字只是加密强大的。对于很多   但是,这是可以接受的。

所以问题是,这对您的申请是否可以接受?如果您更喜欢更安全的RNG,则可以在/ dev / random上读取字节。这个设备的主要不便之处在于:如果Linux内核无法收集足够的熵,它可以无限期地阻塞。还有其他加密安全的RNG,如EGD

或者,如果您的主要关注点是执行速度,并且如果您只需要一些蒙特卡罗方法的“轻度随机性”(即不可预测性无关紧要,均匀分布确实如此),您可以考虑生成随机二进制文件一次并多次使用,至少是为了开发。