How can I generate 10 MB files from
/dev/urandom filled with:
ASCII 1s and 0s
ASCII numbers between 0 and 9
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.Sign up to join this community
If you consider that the actual value for each byte you receive from
</dev/urandom is only significant in that it represents a successful chance occurrence of that byte's value as determined by the PRNG, then you'll realize that whether or not an input byte matches the value for the ones you're looking for is not nearly as important as how often it does. If the PRNG is any good, then any byte in the ASCII spectrum should have a 1/256 chance of occurring for each byte you read.
If you wish to narrow that spectrum to some ASCII subset, then the most efficient way to handle that is to simultaneously broaden the occurrence chance for those chars in your subset and remove the chances of any other.
tr is very good at this, as it allows you to convert chars in a specified range to so many occurrences of a replacement char. Like this:
d=$(printf '[%d*25]' 1 2 3 4 5 6 7 8 9) </dev/urandom LC_ALL=C tr '\0-\377' "$d[0*]"
There are a few things going on there, and they are:
trin the next line. Each
square-bracketed value is a conversion target for
*25value represents how many members of a range in order as specified in
tr's first argument should target this char for conversion.
trto convert all input bytes according to the value in
$d. This means that the bytes
\0-\30(or the first 25 bytes in the range) are converted to ones,
\31-\61to twos and so on.
The result is that all input is converted to only digits across an (almost) even distribution of randomness - and so every byte is used, but they all wind up being only the ones you want. With the above example, though, there is a 4% greater chance that a 0 will occur in
tr's output than any of the other bytes. If this is a problem, you can also do:
LC_ALL=C </dev/urandom \ tr '\0-\377' "[\0*5]$d[0*]" | tr -d \\0
...which resolves that issue.
Now, for the 10M thing, this will work:
TR PIPELINE | dd bs=4k count=2560