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

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

如何从/dev/urandom充满以下内容的文件中生成 10 MB 文件:

  • ASCII 1 和 0

  • 0 到 9 之间的 ASCII 数字

答案1

  • 0 到 9 之间的 ASCII 数字

    < /dev/urandom tr -dc '[:digit:]' | head -c 10000000 > 10mb.txt
    
  • ASCII 1 和 0

    < /dev/urandom tr -dc 01 | head -c 10000000 > 10mb.txt
    

答案2

如果您认为接收到的每个字节的实际值</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*]"

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

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

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

    • (重要的)规定每一个读取的字节应该被解释为 ASCII 字节,所以全部读入的字节将为 NUL 到八进制中的任何一个\377
  3. '\0-\377' "$d[0*]"

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

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

LC_ALL=C </dev/urandom \
tr '\0-\377' "[\0*5]$d[0*]" | 
tr -d \\0

...这解决了这个问题。

现在,对于 10M 的事情,这将起作用:

TR PIPELINE | dd bs=4k count=2560

相关内容