How to get a random string of 32 hexadecimal digits through command line?

BashRandom

Bash Problem Overview


I'd like to put together a command that will print out a string of 32 hexadecimal digits. I've got a Python script that works:

python -c 'import random ; print "".join(map(lambda t: format(t, "02X"), [random.randrange(256) for x in range(16)]))'

This generates output like:

6EF6B30F9E557F948C402C89002C7C8A 

Which is what I need.

On a Mac, I can even do this:

uuidgen | tr -d '-'

However, I don't have access to the more sophisticated scripting languages ruby and python, and I won't be on a Mac (so no uuidgen). I need to stick with more bash'ish tools like sed, awk, /dev/random because I'm on a limited platform. Is there a way to do this?

Bash Solutions


Solution 1 - Bash

If you have hexdump then:

hexdump -vn16 -e'4/4 "%08X" 1 "\n"' /dev/urandom

should do the job.

Explanation:

  • -v to print all data (by default hexdump replaces repetition by *).
  • -n16 to consume 16 bytes of input (32 hex digits = 16 bytes).
  • 4/4 "%08X" to iterate four times, consume 4 bytes per iteration and print the corresponding 32 bits value as 8 hex digits, with leading zeros, if needed.
  • 1 "\n" to end with a single newline.

Solution 2 - Bash

If you are looking for a single command and have openssl installed, see below. Generate random 16 bytes (32 hex symbols) and encode in hex (also -base64 is supported).

openssl rand -hex 16

Solution 3 - Bash

There three ways that I know of:

#!/bin/bash

n=16 

# Read n bytes from urandom (in hex):
xxd -l "$n" -p                    /dev/urandom | tr -d " \n" ; echo
od  -vN "$n" -An -tx1             /dev/urandom | tr -d " \n" ; echo
hexdump -vn "$n" -e ' /1 "%02x"'  /dev/urandom ; echo

Use one, comment out the other two.

Solution 4 - Bash

Here are a few more options, all of which have the nice property of providing an obvious and easy way to directly select the length of the output string. In all the cases below, changing the '32' to your desired string length is all you need to do.

#works in bash and busybox, but not in ksh
tr -dc 'A-F0-9' < /dev/urandom | head -c32

#works in bash and ksh, but not in busybox
tr -dc 'A-F0-9' < /dev/urandom | dd status=none bs=1 count=32

#works in bash, ksh, AND busybox! w00t!
tr -dc 'A-F0-9' < /dev/urandom | dd bs=1 count=32 2>/dev/null

EDIT: Tested in different shells.

Solution 5 - Bash

Try:

xxd -u -l 16 -p /dev/urandom

Example output:

C298212CD8B55F2E193FFA16165E95E3

And to convert it back to binary:

echo -n C298212CD8B55F2E193FFA16165E95E3 | xxd -r -p

Solution 6 - Bash

If you want to generate output of arbitrary length, including even/odd number of characters:

cat /dev/urandom | hexdump --no-squeezing -e '/1 "%x"' | head -c 31

Or to maximize efficiency over readability/composeability:

hexdump --no-squeezing -e '/1 "%x"' -n 15 /dev/urandom

Solution 7 - Bash

Here is a version not using dev/random:

awk -v len=32 'BEGIN {
    srand('$RANDOM');
    while(len--) {
        n=int(rand()*16);
        printf("%c", n+(n>9 ? 55 : 48));
    };}'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnaView Question on Stackoverflow
Solution 1 - BashRenaud PacaletView Answer on Stackoverflow
Solution 2 - BashtouzokuView Answer on Stackoverflow
Solution 3 - Bashuser2350426View Answer on Stackoverflow
Solution 4 - BashcavemanView Answer on Stackoverflow
Solution 5 - BashJay SullivanView Answer on Stackoverflow
Solution 6 - BashVasiliNovikovView Answer on Stackoverflow
Solution 7 - BashRichard TingstadView Answer on Stackoverflow