我正在尝试使用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)但是我想为了好奇而想出来......有一种明显的方法来改善这个?
答案 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。
或者,如果您的主要关注点是执行速度,并且如果您只需要一些蒙特卡罗方法的“轻度随机性”(即不可预测性无关紧要,均匀分布确实如此),您可以考虑生成随机二进制文件一次并多次使用,至少是为了开发。