3

The time it takes to generate a 10-length string using the following command is acceptable.

cat /dev/urandom | strings -n 10 | head -n 1

While generating a 255-length string takes forever.

cat /dev/urandom | strings -n 255 | head -n 1

I have tried it with other length like 30. It’s much longer than it takes with 10. I have compared the consumed time many times. Why is this?

Giacomo1968
  • 58,727
Tiina
  • 3,297

2 Answers2

5

From man 1 strings:

For each file given, GNU strings prints the printable character sequences that are at least 4 characters long (or the number given with the options below) and are followed by an unprintable character.

What are the odds that strings encounters 255 consecutive printable characters in a random stream? Low, unless you wait long enough.

The below command doesn't require consecutive printable characters in the input stream. It purges non-printable characters.

< /dev/urandom tr -dc '[:print:]' | head -c 255

Note: GNU tr works one byte at a time (it has no concept of multibyte characters); then GNU head -c counts bytes. Therefore:

  • with GNU tools you won't get any printable non-ASCII character (e.g. Ł) from the above command;
  • with non-GNU implementation of tr (compare this answer) you may get less than 255 characters in exactly 255 bytes;
  • with non-GNU implementation of tr the last character may be invalid; this will happen if head cuts the stream in the middle of a multibyte character.
1

If you're looking for a lot of "randomness" quickly, you might consider not using /dev/urandom directly, but instead use a plain dm-crypt device with a random key.

It's perfect for overwriting a device, but combining it with a fixed length file you could get a fixed length of random data without waiting for /dev/urandom at all.

(Though your main problem appears to have been waiting for consecutive characters with strings, this could still be useful & quicker, solving your "subject line problem")

Here's the relevant section from cryptsetup's FAQs:

2.19 How can I wipe a device with crypto-grade randomness?

The conventional recommendation if you want to not just do a zero-wipe is to use something like

cat /dev/urandom >  <taget-device>

That is very slow and painful at 10-20MB/s on a fast computer. Using cryptsetup and a plain dm-crypt device with a random key, it is much faster and gives you the same level of security. The defaults are quite enough.

For device set-up, do the following:

cryptsetup open --type plain -d /dev/urandom /dev/<block-device> to_be_wiped

This maps the container as plain under /dev/mapper/to_be_wiped with a random password. For the actual wipe you have several options. Simple wipe without progress-indicator:

cat /dev/zero > /dev/mapper/to_be_wiped

Progress-indicator by dd_rescue:

dd_rescue -w /dev/zero /dev/mapper/to_be_wiped

Progress-indicator by my "wcs" stream meter (available from http://www.tansi.org/tools/index.html ):

cat /dev/zero | wcs > /dev/mapper/to_be_wiped

Or use plain "dd", which gives you the progress when sent a SIGUSR1, see the dd man page.

Remove the mapping at the end and you are done.


So creating a fixed length file of say 10M named 10

fallocate -l 10M 10

Setup the plain dm-crypt on 10, named /dev/mapper/crypt10

cryptsetup -v open --type plain -d /dev/urandom 10 crypt10

Now "overwriting" 10 with crypto-grade randomness (with dd) & close the mapping

dd if=/dev/zero of=/dev/mapper/crypt10
cryptsetup -v close crypt10

Now you've got 10M of random data in the file 10 to play with, or delete all the non-printable characters using Kamil's answer: "translating" the whole file to the printable file named 10-printable would be

tr -dc '[:print:]' < 10  > 10-printable

leaving about 3.8M of printable data in 10-printable.

Xen2050
  • 14,391