Using /dev/random, /dev/urandom to generate random data

You can use od to get numbers out of /dev/random and /dev/urandom.

For example,

2 byte unsigned decimal integers,

$ od -vAn -N2 -tu2 < /dev/urandom
24352

1 byte signed decimal integer,

$ od -vAn -N1 -td1 < /dev/urandom
-78

4 byte unsigned decimal integers,

$ od -vAn -N4 -tu4 < /dev/urandom
3394619386

man od for more information on od.


Some shells (e.g. bash(1)) have a $RANDOM "variable" that gives random numbers.


Shelling out to od is slow. Using the built-in bash function is 100s of times faster. Would you like a 60-bit random integer? Do this:

((RND=((RANDOM<<15|RANDOM)<<15|RANDOM)<<15|RANDOM))

That will give you a random number in the range of 0 to 1,152,921,504,606,846,975. You can scale that down with a modulo division to whatever range you want.

Here's a practical example. Let's say, I want to read one random sector from my hard disk, for example, to wake up the disk from a standby state. I can do this:

#!/bin/bash
DEV=/dev/sda  # Let's say that this is the device we want to spin up.

# Get the device geometry...
read -d- SIZE64 BS <<<$(blockdev --getsize64 --getbsz $DEV)
((SECTORS=SIZE64/BS)) # The total number of $BS-sized sectors on that device.

((RND=(RANDOM<<15|RANDOM)<<15|RANDOM)) # Generate a 45-bit random number.
((SECT=RND%SECTORS)) # The random sector that we will now read...

dd if=$DEV of=/dev/null bs=$BS skip=$SECT count=1 >/dev/null 2>&1

Done.

(Note: In this example I decided that a 45-bit random integer would be more than enough, and also, a tiny little bit faster than using 60 bits.)


Update:

To give some quantitative backup for the above speed claim:


~# time for i in {1..10000} ;do RND=$(od -An -N7 -tu8 /dev/urandom) ;done

real    0m45.647s
user    0m17.540s
sys     0m28.807s

~# time for i in {1..10000} ;do ((RND=((RANDOM<<15|RANDOM)<<15|RANDOM)<<15|RANDOM)) ;done

real    0m0.112s
user    0m0.105s
sys     0m0.007s