Random

使用 /dev/urandom 生成帶有 ASCII 數字的文件?

  • March 25, 2015

如何生成 10 MB 的文件,/dev/urandom其中包含:

  • ASCII 1 和 0
  • 0 到 9 之間的 ASCII 數字
  • 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

如果您認為您收到的每個字節的實際值</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
  1. LC_ALL=C
  • 這*(重要的是)要求讀取的每個字節都應解釋為 ASCII 字節,因此讀取的所有*字節都將是 NUL 到 octal 中的任何一個\377
  1. '\0-\377' "$d[0*]"
  • 這指示tr根據 中的值轉換所有輸入字節$d。這意味著字節\0-\30 *(或範圍中的前 25 個字節)*被轉換為\31-\611、2 等。

結果是所有輸入都僅轉換為*(幾乎)均勻分佈的隨機性中的數字-因此使用了每個*字節,但最終它們都只是您想要的。tr但是,對於上面的範例,在’ 的輸出中出現 0 的可能性比任何其他字節高 4% 。如果這是一個問題,您還可以執行以下操作:

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

…解決了這個問題。

現在,對於 10M 的東西,這將起作用:

TR PIPELINE | dd bs=4k count=2560

引用自:https://unix.stackexchange.com/questions/150957