generate random base 16

How would you use bash to generate a random 32 digit number base 16?

Like this one:

0cc06f2fa0166913291afcb788717458

One way:

dd count=1024 if=/dev/random 2>/dev/null |md5sum|sed 's/-//'

Not efficient, but it works.

Using bash internals exclusively you can:

printf "%04x" $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM

edit: oops range of RANDOM is only 0 - 32767; adjusted answer below (not quite so nice)

for ((i=0;i<10;i++)) {
   printf "%03x" $((RANDOM%4096))
} ; printf "%02x" $((RANDOM%256))

or

printf "%03x%03x%03x%03x%03x%03x%03x%03x%03x%03x%02x" \
    $((RANDOM%4096)) $((RANDOM%4096)) \
    $((RANDOM%4096)) $((RANDOM%4096)) \
    $((RANDOM%4096)) $((RANDOM%4096)) \
    $((RANDOM%4096)) $((RANDOM%4096)) \
    $((RANDOM%4096)) $((RANDOM%4096)) \
    $((RANDOM%256))
x=$(dd if=/dev/random bs=16 count=1 2>/dev/null | od -An -tx1 | tr -d ' \t\n')

Regards,
Alister

od -N32 -x < /dev/urandom | head -n1 |  cut -b9- | sed 's/ //gi'

How about:

openssl rand -hex 16
1 Like

Not good on FreeBSD 6.2-RELEASE FreeBSD (bash)
Gets

$ openssl rand -hex16
Usage: rand [options] num
where options are
-out file             - write to file
-engine e             - use engine e, possibly a hardware device.
-rand file:file:... - seed PRNG from files
-base64               - encode output

Using awk...

$ rand=$(awk 'BEGIN{srand();for(i=1;i<=32;i++)printf "%x", int(rand()*16)}')

$ echo $rand
b9645ca2f0c5f55ed1411258d57b5bb5

$

That's a great use of od -N... to obviate dd . But the rest of the solution could be more robust.

cut -b9- depends on the width of the offset field which is allowed to vary among implementations. Better to simply suppress the input offset with od -An ... .

head -n1 assumes that the first line will contain exactly what's needed, nothing more and nothing less. There is no guarantee that the first line will contain 16 bytes worth of data (especially since you're reading twice as many bytes as needed).

Those assumptions may be true for your od, but they may not be true for all. Even if they are, when it can be trivially accomplished, it's often best to not depend on unspecified behavior.

In this case, it is not a problem, but if an odd number of bytes is read, then od -x ... will add a nullbyte of padding to complete the final 2-byte output block. This results in one too many bytes (two too many hex characters) in the result. The more general solution should use a 1-byte output format.

od -N16 -An -tx1 < /dev/random | tr -d '[:space:]'

Regards,
Alister