使用 /dev/urandom 生成带有 ASCII 数字的文件?

pro*_*ngs 7 ascii random

如何从/dev/urandom填充中生成 10 MB 文件:

  • ASCII 1 和 0

  • 0 到 9 之间的 ASCII 数字

hip*_*vet 7

  • @programings,不,只是与 `< /dev/urandom perl -pe 'BEGIN{$/=\4096}; 相比效率不高;例如,$_=unpack("b*",$_)'`。 (3认同)
  • 请注意,例如,第二个需要从 /dev/uramdom 读取(平均)1280 MB 以获得 10 MB 的输出。参见`pv -cN a < /dev/urandom | tr -cd 01 | pv -cN b > /dev/null` (2认同)

mik*_*erv 5

如果您认为您收到的每个字节的实际值</dev/urandom仅在它表示由 PRNG 确定的该字节值的成功机会发生时才有意义,那么您将意识到输入字节是否与以下值匹配您正在寻找的那些并不像它搜索的频率那么重要。如果 PRNG 有任何好处,那么对于您读取的每个字节,ASCII 频谱中的任何字节都应该有 1/256 的机会发生。

如果您希望将该范围缩小到某个 ASCII 子集,那么处理该问题的最有效方法是同时扩大子集中这些字符的出现机会并消除任何其他字符的出现机会。tr非常擅长这一点,因为它允许您将指定范围内的字符转换为多次出现的替换字符。像这样:

d=$(printf '[%d*25]' 1 2 3 4 5 6 7 8 9)
</dev/urandom LC_ALL=C tr '\0-\377' "$d[0*]"
Run Code Online (Sandbox Code Playgroud)

那里发生了一些事情,它们是:

  1. d=[[char]*[num]]...

    • 在这里,我只是设置了一个包含第二个参数的 var,我的意思tr是在下一行提交。每个[]方括号内的值都是 的转换目标tr,每个*25值表示按tr的第一个参数中指定的顺序排列的范围内有多少个成员应该以此字符为目标进行转换。
  2. LC_ALL=C

    • (重要)要求读取的每个字节都应解释为 ASCII 字节,因此所有读取的字节都将是 NUL 到八进制中的任何一个\377
  3. '\0-\377' "$d[0*]"

    • 这指示tr根据中的值转换所有输入字节$d。这意味着字节\0-\30 (或范围中的前 25 个字节)将转换\31-\61为 1、2 等。

结果是所有输入都被转换为(几乎)均匀分布的随机数 - 因此每个字节都被使用,但它们最终都只是你想要的。但是,在上面的示例中,tr与其他任何字节相比,在 的输出中出现 0 的可能性要高 4% 。如果这是一个问题,您还可以执行以下操作:

LC_ALL=C </dev/urandom \
tr '\0-\377' "[\0*5]$d[0*]" | 
tr -d \\0
Run Code Online (Sandbox Code Playgroud)

...解决了这个问题。

现在,对于 10M 的东西,这将起作用:

TR PIPELINE | dd bs=4k count=2560
Run Code Online (Sandbox Code Playgroud)