我在 ubuntu 系统上运行以下命令:
dd if=/dev/random of=rand bs=1K count=2
Run Code Online (Sandbox Code Playgroud)
但是,每次运行它时,我都会得到一个不同大小的文件。为什么是这样?如何生成填充随机数据的给定大小的文件?
Gil*_*il' 43
您正在观察dd的特殊行为与 Linux 的特殊行为的组合/dev/random。顺便说一下,两者都很少是适合这项工作的工具。
Linux/dev/random很少返回数据。它基于伪随机数发生器中的熵以非常快的速度消失的假设。由于收集新的熵很慢,/dev/random通常一次只放弃几个字节。
dd是一个旧的、古怪的程序,最初打算在磁带设备上运行。当您告诉它读取一个 1kB 的块时,它会尝试读取一个块。如果读取返回少于 1024 个字节,很难,这就是你所得到的。所以dd if=/dev/random bs=1K count=2打了两个read(2)电话。由于它是从 读取的/dev/random,这两个read调用通常只返回几个字节,数量取决于可用的熵。另请参阅dd 何时适合复制数据?(或者,什么时候 read() 和 write() 是部分的)
除非您正在设计操作系统安装程序或克隆程序,否则永远不要/dev/random在 Linux 下使用/dev/urandom. 该urandom手册页有所误导; /dev/urandom实际上适用于密码学,甚至适用于生成长寿命密钥。唯一的限制/dev/urandom是它必须提供足够的熵;Linux 发行版通常会在重新启动之间保存熵,因此唯一可能没有足够熵的时间是全新安装。熵在实际中不会消失。有关更多信息,请阅读/dev/urandom 中的 rand 是否安全用于登录密钥?和喂养 /dev/random 熵池?.
使用或 之类的dd工具可以更好地表达 的大多数用途。如果您想要 2kB 的随机字节,请运行headtail
head -c 2k </dev/urandom >rand
Run Code Online (Sandbox Code Playgroud)
使用较旧的 Linux 内核,您可以逃脱
dd if=/dev/urandom of=rand bs=1k count=2
Run Code Online (Sandbox Code Playgroud)
因为很/dev/urandom高兴返回了请求的字节数。但是从内核 3.16 开始就不再如此,现在限制为 32MB。
一般而言,当您需要使用dd提取固定数量的字节并且其输入不是来自常规文件或块设备时,您需要逐字节读取:dd bs=1 count=2048。
Bru*_*ger 11
从man 4 random在RHEL 5盒:
读取时,/dev/random 设备将仅返回熵池中估计的噪声位数内的随机字节。
我在那台机器上得到大小为 213 字节的文件。回到人4随机:
读取时,/dev/urandom 设备将返回所请求的字节数。
我从每次调用中得到 2048 个字节 dd if=/dev/urandom of=rand bs=1K count=2
我得出结论,差异是由于您的机器在调用之间产生了多少熵 dd if=/dev/random ...
为什么会dd丢数据?... Gilles提出了这个引人入胜的问题dd:
dd 何时适合复制数据?(或者,什么时候是 read() 和 write() 部分的)
这是该问题的摘录:
*...不难将 dd 归咎于错误;例如,试试这个代码:**
yes | dd of=out bs=1024k count=10
并检查输出文件的大小(它可能远低于 10MB)。
除了我的评论(在你的问题结束时),像这样的东西值得关注......它会在 file 中捕获你的字节$trnd。我半随意地选择了 bs=8
移动你的鼠标,看着它加速。
在我的计算机空闲(AFK 且没有网络活动)的情况下,在耗尽熵池后,仅收集1192字节花了2小时12 分钟,此时我取消了它。
然后,随着我不断移动鼠标,收集相同数量的字节所需的时间相对较短1分15 秒。
这很清楚地表明,收集熵不是基于 CPU 速度,而是基于随机事件,并且我的 Ubuntu 系统使用鼠标作为其重要的随机因素之一。
get=2048
trnd=/tmp/$USER.rnd; >"$trnd"
while (( $(wc -c <"$trnd") < $get )) ;do
dd if=/dev/random bs=8 count=1 2>/dev/null >>"$trnd"
echo -n "itt: $((i+=1)) ct: "; wc -c <"$trnd"
done
truncate -s $get "$trnd"
echo -e "\nfinal count: "; wc -c <"$trnd"
Run Code Online (Sandbox Code Playgroud)