我想生成一个大小为2MB的随机文件,其中包含Linux / Windows中0和1以及我的一个项目。我在linux中试过这个命令:
$ time dd if=/dev/urandom of=/dev/null bs=1M count=2
但是urandom只从内核中获取随机数据,只是复制到我不需要的文件。关于这个的任何想法?谢谢!
答案 0 :(得分:1)
Colin的解决方案效率极低,因为一种方法会创建一个庞大的列表,然后从中进行选择(因此,如果您想要更大的文件,它将无法正常工作),而另一种方法只会生成一个字符循环
$ time (python3 -c "import random; print(''.join('{0}'.format(n) for n in
random.sample([0,1]*16*1024*1024, 2*1024*1024)));" > /dev/null)
real 0m4,034s
user 0m3,856s
sys 0m0,137s
$ time (python3 -c "from __future__ import print_function; import random;
[print(random.randint(0,1), end='') for i in range(0, 2*1024*1024)];" > /dev/null)
real 0m6,461s
user 0m6,435s
sys 0m0,016s
$ time (perl -077 -ne 'print unpack("b*")' < /dev/urandom | head -c2M >/dev/null)
real 0m0,007s
user 0m0,006s
sys 0m0,003s
head -c2M
这里是将输出限制为2 MB
从理论上讲,在一个周期中处理8个字节而不是仅仅1个字节应该更快,尽管我不知道如何使用perl提高效率
$ time (</dev/urandom perl -nle 'BEGIN{$/=\8; $,=""} printf("%.64b", unpack("Q"))' |
head -c2M >/dev/null)
real 0m0,027s
user 0m0,019s
sys 0m0,010s
在What's the fastest way to generate a 1 GB text file containing random digits?中,有一些答案可以以 GB或每秒数十GB的速度生成带有空格分隔符的 十进制位数。强>。仅生成 binary 值且没有您所需要的空格,应该幅值更快。我已经对其中的一些答案进行了调整,以生成0和1。这是我的Ubuntu 18.04 VM(Core i7-8700,2GB RAM)上的一些基准测试:
$ time (LC_ALL=C tr '\0-\377' '[0*128][1*128]' </dev/urandom | head -c2M >/dev/null)
real 0m0,012s
user 0m0,003s
sys 0m0,012s
$ time (jot -s "" -r -c $((2*1024*1024)) 48 49) >/dev/null
real 0m0,297s
user 0m0,279s
sys 0m0,008s
$ time (shuf -r -n $((2*1024*1024)) -i 0-1 -z | tr -d "\0" >/dev/null)
real 0m0,383s
user 0m0,384s
sys 0m0,000s
实际上,/dev/urandom
的速度还不够快,可以用</dev/zero openssl enc -aes-128-ctr -nosalt -pass file:/dev/urandom
来替换,AES instruction set可以在CPU上提供更快的随机字节流。这是输出20MB文件的时间(因为上述tr
命令的2MB运行时间非常短,这使得time
返回的结果千差万别)
$ time (</dev/zero openssl enc -aes-128-ctr -nosalt -pass file:/dev/urandom 2> /dev/null |
LC_ALL=C tr '\0-\377' '[0*128][1*128]' | head -c20M >/dev/null)
real 0m0,023s
user 0m0,016s
sys 0m0,023s
$ time (</dev/zero openssl enc -aes-128-ctr -nosalt -pass file:/dev/urandom 2> /dev/null |
perl -077 -ne 'print unpack("b*")' | head -c20M >/dev/null)
real 0m0,038s
user 0m0,024s
sys 0m0,019s
$ time (</dev/zero openssl enc -aes-128-ctr -nosalt -pass file:/dev/urandom 2> /dev/null |
jot -s "" -r -c $((20*1024*1024)) 48 49 >/dev/null)
real 0m2,820s
user 0m2,820s
sys 0m0,000s
答案 1 :(得分:0)
你需要快速的东西吗?否则你可以试试(对我来说花了〜2mn):
$ time (for i in `seq 1 $((2*1024*1024))`;
do echo -n $(($RANDOM%2)); done > random.txt)
您可以通过减少$ RANDOM来加快速度,例如:
$ time (i=$((2*1024*1024)); a=0; while [ $i -gt 0 ]; do if [ $a -lt 2 ]; then
a=$RANDOM; fi; echo -n "$(($a%2))"; let a=$a/2; let i=$i-1; done > random.txt)
在我的情况下,它快了近4倍。它的作用是提取数字的正确位,直到数字不再为1。因此可能会稍微偏向1。
但是,如果您想要快速解决方案,则应该明显不要使用shell脚本语言。你可以在python中轻松完成(在我的情况下这需要约2秒):
$ time (python -c "import random; print(''.join('{0}'.format(n) for n in
random.sample([0,1]*16*1024*1024, 2*1024*1024)));" > random.txt)
我在这里随机抽取0和1的大清单。但是,我不确定抽样对随机性质的影响。如果列表与样本相比是巨大的,我认为它应该提供高质量的结果,但是它只有8倍大,所以它可能会产生可衡量的影响。
请注意,随机性并不像看起来那么容易。我在这里提出的解决方案的输出并不都具有相同的属性,并且验证它具有哪些通常是复杂的。您可能希望以“更好”的方式交易业绩。随机性,在这种情况下python中的这个版本可能会更好(在我的情况下约为6秒):
$ time (python -c "from __future__ import print_function; import random;
[print(random.randint(0,1), end='') for i in range(0, 2*1024*1024)];" > random.txt)
这里,random.randint应该提供均匀分布的结果。