在我当前的 Linux 系统(Debian Jessie amd64)上,我的dd
使用行为有所不同/dev/urandom
(/dev/random
行为已正确记录)。如果我天真地想要 1G 的随机数据:
$ dd if=/dev/urandom of=random.raw bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB) copied, 2.2481 s, 14.9 MB/s
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)
在这种情况下,只存储了 34MB 的随机数据,而如果我使用多次读取:
$ dd if=/dev/urandom of=random.raw bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 70.4749 s, 14.9 MB/s
Run Code Online (Sandbox Code Playgroud)
然后我正确地得到了我的 1G 随机数据。
的文档/dev/urandom
相当难以捉摸:
从 /dev/urandom 设备读取不会阻塞等待更多熵。因此,如果熵池中没有足够的熵,则返回值理论上容易受到对驱动程序使用的算法的加密攻击。当前未分类的文献中没有关于如何做到这一点的知识,但理论上可能存在这种攻击。如果这是您的应用程序中的一个问题,请改用 /dev/random。
我猜文档暗示urandom
.
我还猜测我的系统上熵池的大小是 34MB,这可以解释为什么read
1G 中的第一个失败了大约 34MB。
但我的问题是我怎么知道我的熵池的大小?或者被dd
另一个因素阻止(与urandom
?相关的某种计时问题)。
don*_*sti 18
如果您检查从 /dev/urandom 读取在 33554431 字节后给出 EOF并遵循讨论,它会指向另一个错误报告,其中 Ted Tso 指出...
...提交 79a8468747c5 导致读取大于 32MB 导致 read(2) 系统调用仅返回 32MB。也就是说,它会导致短读。POSIX 总是允许短读(2),任何程序都必须检查短读。
dd 的问题在于 POSIX 要求 count=X 参数基于读取,而不是基于字节。这可以通过 iflag=fullblock 更改。
根据gnu dd
手册:
Note if the input may return short reads as could be the case when reading from
a pipe for example, ‘iflag=fullblock’ will ensure that ‘count=’ corresponds to
complete input blocks rather than the traditional POSIX specified behavior of
counting input read operations.
Run Code Online (Sandbox Code Playgroud)
所以如果你添加iflag=fullblock
:
dd if=/dev/urandom of=random.raw bs=1G count=1 iflag=fullblock
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 65.3591 s, 16.4 MB/s
Run Code Online (Sandbox Code Playgroud)
这实际上由 确认dd
,如果您省略iflag
并增加32
读取计数,即大致32
x
33554431
字节=
1073741792
字节1G
(或1.1GB
根据dd
man
乘法后缀的每个页面部分),它将输出一个简短的警告:
dd if=/dev/urandom of=random.raw bs=1G count=32
dd: warning: partial read (33554431 bytes); suggest iflag=fullblock
0+32 records in
0+32 records out
1073741792 bytes (1.1 GB) copied, 59.6676 s, 18.0 MB/s
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6960 次 |
最近记录: |