Instantly share code, notes, and snippets.

Embed
What would you like to do?
shell/bash generate random alphanumeric string
#!/bin/bash
# bash generate random alphanumeric string
#
# bash generate random 32 character alphanumeric string (upper and lowercase) and
NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
# bash generate random 32 character alphanumeric string (lowercase only)
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
# Random numbers in a range, more randomly distributed than $RANDOM which is not
# very random in terms of distribution of numbers.
# bash generate random number between 0 and 9
cat /dev/urandom | tr -dc '0-9' | fold -w 256 | head -n 1 | head --bytes 1
# bash generate random number between 0 and 99
NUMBER=$(cat /dev/urandom | tr -dc '0-9' | fold -w 256 | head -n 1 | sed -e 's/^0*//' | head --bytes 2)
if [ "$NUMBER" == "" ]; then
NUMBER=0
fi
# bash generate random number between 0 and 999
NUMBER=$(cat /dev/urandom | tr -dc '0-9' | fold -w 256 | head -n 1 | sed -e 's/^0*//' | head --bytes 3)
if [ "$NUMBER" == "" ]; then
NUMBER=0
fi
@blikenoother

This comment has been minimized.

blikenoother commented Jan 4, 2014

Thanks :)

@ilikenwf

This comment has been minimized.

ilikenwf commented Jan 9, 2014

If you need lowercase, tack another pipe and tr '[:upper:]' '[:lower:]' there.

Thanks!

@javouhey

This comment has been minimized.

javouhey commented Feb 14, 2014

Didn't google recently suffered downtime due to the lack of entropy ? Does reading from /dev/urandom ever block ?

@earthmeLon

This comment has been minimized.

earthmeLon commented Feb 18, 2014

@javouhey There are many different problems with entropy, but in regards to using /dev/urandom, it is the preferred method in such an example.

/dev/random seeds /dev/urandom, which is then expanded allowing smaller amounts of entropy to result in larger sets of 'random' data. It is definitely recommended to use /dev/urandom and not /dev/random.

@hkdobrev

This comment has been minimized.

hkdobrev commented Feb 19, 2014

@earthgecko Thank you for this script!

Could you help me with an issue I have? When I run it it works like a charm, but when I put it in another script it hangs.

Specifically I am running it a Composer post-install hook to generate a random salt. I suppose it starts a new child process for the command.

In the Activity Monitor I could see the process is reaching nearly 100% CPU usage.

@hkdobrev

This comment has been minimized.

hkdobrev commented Feb 19, 2014

My problem is most probably caused by: symfony/symfony#9409

cat /dev/urandom outputs a large amount of data which fails when the Symfony\Process library starts it as a child process.

@ghost

This comment has been minimized.

ghost commented Feb 22, 2014

Thanks for your script!

I put this into my .bashrc

random-string()
{
    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-32} | head -n 1
}

Use it like this:

$ random-string
FWtnOOHAjbD6rNxWWEeVOCj7JXSEPGJQ

$  random-string 16
CYmYZRlju4h4SN2l
@dlangille

This comment has been minimized.

dlangille commented Apr 21, 2014

This doesn't work on a Mac:

$ cat /dev/urandom | tr -dc 'a-zA-Z0-9'
tr: Illegal byte sequence

Nor on FreeBSD 9.2:

$ cat /dev/urandom | tr -dc 'a-zA-Z0-9'
tr: Illegal byte sequence

@ghost

This comment has been minimized.

ghost commented Apr 29, 2014

Try this: LC_CTYPE=C tr -dc A-Za-z0-9 < /dev/urandom | fold -w ${1:-32} | head -n 1+}.

@drewwells

This comment has been minimized.

drewwells commented Jun 4, 2014

This works on the CLI, but how is this used in the above script? I'm still getting errors within a shell script.

@jordanmack

This comment has been minimized.

jordanmack commented Jun 7, 2014

Is there any advantage to using fold + head over just head?

NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 32);
@mihigh

This comment has been minimized.

mihigh commented Jun 22, 2014

@dlangille for mac use:
cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1

@wavic

This comment has been minimized.

wavic commented Jun 29, 2014

What about these symbols

!@#$%^&*()_+?><~`';][

etc.

@dmp1ce

This comment has been minimized.

dmp1ce commented Dec 1, 2014

@wavic

#!/bin/bash

NEW_UUID_MORE_CHARACTERS=$(cat /dev/urandom | tr -dc "a-zA-Z0-9!@#$%^&*()_+?><~\`;'" | fold -w 32 | head -n 1)
echo $NEW_UUID_MORE_CHARACTERS
@timbru31

This comment has been minimized.

timbru31 commented Dec 20, 2014

@mihigh
thanks, works like a charm on the mac! :)

@shahakshay94

This comment has been minimized.

shahakshay94 commented Jan 16, 2015

what if i want my string of any particular length only let's just say , in this case , I want it of 10 characters long only ?

@ricasiano

This comment has been minimized.

ricasiano commented Jan 20, 2015

@shahaksay94 fold it to 10 instead of 32

@ftonello

This comment has been minimized.

ftonello commented Jan 22, 2015

Nice. Thanks!

@ggrandes

This comment has been minimized.

ggrandes commented Jan 27, 2015

# Without visual similar chars: IOl01
tr -dc 'A-HJ-NP-Za-km-z2-9' < /dev/urandom | dd bs=32 count=1 status=none
@bjarthur

This comment has been minimized.

bjarthur commented Jan 27, 2015

+1 @jmack for head -c instead of fold

@axlm

This comment has been minimized.

axlm commented Feb 10, 2015

@dlangille, it works on FreeBSD if you are root.

@expz

This comment has been minimized.

expz commented Feb 20, 2015

fewer random bytes could be discarded:

base64 /dev/urandom | tr -d '/+' | dd bs=32 count=1 status=none

or to delete o, O, and 0, for example:

base64 /dev/urandom | tr -d '/+oO0' | dd bs=32 count=1 status=none

or as a function:

mkpasswd() { base64 /dev/urandom | tr -d "/+$2" | dd bs="$1" count=1 status=none | xargs echo; }

used like: mkpasswd 32 'oO0' or mkpasswd 32 '0-9'

@parasyte

This comment has been minimized.

parasyte commented Apr 20, 2015

👍 @expz

Instead of status=none you can also redirect stderr to /dev/null:

base64 /dev/urandom | tr -d '/+' | dd bs=32 count=1 2>/dev/null
@chashish13

This comment has been minimized.

chashish13 commented Apr 21, 2015

Suggest, if I want Special character in the output of following command.

strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 8 | tr -d '\n'; echo;

@cirosantilli

This comment has been minimized.

cirosantilli commented Apr 28, 2015

@jordanmack +1. Stack overflow just rocks for this kind of thing: http://stackoverflow.com/questions/101362/how-do-you-generate-passwords

@jfprevost

This comment has been minimized.

jfprevost commented Jun 26, 2015

for a full bunch of random chars:

tr -dc [:graph:] < /dev/urandom | head -c 32

@expz

This comment has been minimized.

expz commented Jul 6, 2015

If you're going to generate just one password, fine, there's a million ways. But if you're going to generate a million, do you really want to discard 90% of the random bits your computer generates? It seems to me that the passwords will come out as a different kind of 'random'. That's why I suggest a different solution.

@BardiaAfshin

This comment has been minimized.

BardiaAfshin commented Jul 8, 2015

on mac

``bash
○ → cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
tr: Illegal byte sequence

@yangsibai

This comment has been minimized.

yangsibai commented Jul 10, 2015

@BardiaAfshin

LC_ALL=C; cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
@jkwages

This comment has been minimized.

jkwages commented Aug 1, 2015

Soooo....what if I wanted to create a file of generated passwords using this script. Say 1000 of them. I know how to generate multiples, but is it possible to save them to a text file for later use?

@fnkr

This comment has been minimized.

fnkr commented Aug 3, 2015

Why don't use head -c instead of fold? Benefits: performance, works on Git Bash under Windows too.

cat /dev/urandom | tr -dc 'a-z0-9' | head -c 32

https://gist.github.com/fnkr/de448cbf9f45038d69bb

@user454322

This comment has been minimized.

user454322 commented Sep 3, 2015

LC_ALL=C; dd if=/dev/urandom bs=256 count=1 2> /dev/null | tr -dc 'a-zA-Z0-9' | head -c 32; echo

Instead of cating /dev/urandom, just read 256 bytes, which are enough to have a 32 char string.

@denzuko

This comment has been minimized.

denzuko commented Oct 1, 2015

would be nice if everyone would stop catting all over themselves as the < filename parameter does the same thing.

Here's an example that works on all POSIX systems even Sun unix and AIX and is always going to get 32 characters (ie a DWORD byte read 8 times):

   tr -dc '[:alnum:]' < /dev/urandom  | dd bs=4 count=8 2>/dev/null
@denzuko

This comment has been minimized.

denzuko commented Oct 1, 2015

@jkwages yes just append the >> my.password.lst_file to the command to pipe into a file or subshell.

What the >> part means is take stdout from the pipe line/command and append to the end of file named my.password.lst_file. Also, the > means overwrite the file with the latest output.

Example:

for idx in `seq 1 1000`; do
    tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=8 2>/dev/null >> password.lst
done

An async threaded version would look like this:

for idx in `seq 1 1000`; do
    (tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=8 2>/dev/null >>password.lst) & # thread number 1
    (tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=8 2>/dev/null >>password.lst) & # thread number 2
done
@mckyj57

This comment has been minimized.

mckyj57 commented Nov 17, 2015

Perl one-liner in case you only want to have one dependency:

perl -e '@c=("A".."Z","a".."z",0..9);$p.=$c[rand(scalar @c)] for 1..32; print "$p\n"'

Probably not as random as it could be, but should be good enough for this purpose.

@jhyland87

This comment has been minimized.

jhyland87 commented Jan 14, 2016

FYI:

$ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
tr: Illegal byte sequence

This is on ISX Yosemite though

I used the one-liner by @mckyj57, which works great. Thanks!

@u2mejc

This comment has been minimized.

u2mejc commented Jan 29, 2016

IMHO here are some simpler options, pick the right tool for the job:

  • Inside bash scripts:
    • Random temporary files: mktemp
    • Random number: echo $RANDOM
  • Strings, length is players choice, these should be 32 bytes off the top of my head:
    • (lowercase alpha and numbers) openssl rand -hex 16
    • (all alpha, numbers and +/= chars): openssl rand -base64 24
@ernestm

This comment has been minimized.

ernestm commented Feb 17, 2016

cat /dev/urandom | env LC_CTYPE=C tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1

works for me on El Capitan but it triggers "set -e" for some reason and will stop scripts with set -e going; I've run the pieces of this and don't see any nonzero exit codes and am not sure why, but FYI.
Same thing with

env LC_CTYPE=C tr -dc '[:alnum:]' < /dev/urandom | dd bs=4 count=2 2>/dev/null

I'm just using $RANDOM now as a workaround but would like a slightly larger space...

@swklzr

This comment has been minimized.

swklzr commented Jun 6, 2016

  1. 400+ out / 5 sec
    $(base64 /dev/urandom | tr -d '/+' | head -c 32 | tr '[:upper:]' '[:lower:]')
  2. 1000 out / 5 sec
    $(head -c 16 /dev/urandom | md5sum | head -c 32)
@ARandomScientist

This comment has been minimized.

ARandomScientist commented Jun 9, 2016

Made an interactive version.

#!/usr/bin/env bash
###############

echo ""
echo "Welcome to the random alphanumeric sequence generator."
echo 'Random sequence generation taken from: gist.github.com/earthgecko/3089509'
echo ""

echo -n "Enter desired sequence length: "
read input_variable

cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $input_variable | head -n 1

echo ""
echo "You're welcome."

I don't particularly care for how I used echo to separate text bodies. I feel as if there's a more elegant way to do that.

I'm actually pretty new to coding in general, so if you have any tips, please don't hesitate to give them.

@apalii

This comment has been minimized.

apalii commented Jun 10, 2016

"simple is better then complex"

PASSWORD=`pwgen -s 10 1`

man pwgen - for more details

@pabloernesto

This comment has been minimized.

pabloernesto commented Aug 27, 2016

These two commands generate random passwords and passphrases, respectively. You can use the first command with the right configuration file to generate random alphanumeric strings.

shuf --random-source=/dev/urandom --repeat --head-count=20 file_with_characters | tr --delete '\n'

shuf --random-source=/dev/urandom --repeat --head-count=7 file_with_words | tr '\n' ' '

The password generator requires a file_with_characters containing all the characters you want the password to use, one character per line, and exactly one time each. The file must not contain blank lines, and lines must be newline-terminated.

The passphrase generator requires a file_with_words containing all the words you want the passphrase to use, one word per line, and exactly one time each. The file must not contain blank lines, and lines must be newline-terminated.

The --head-count option specifies the length of the password--in characters--or passphrase--in words.

@fuweid

This comment has been minimized.

fuweid commented Sep 15, 2016

Very very useful script!!!

But I have still question here:
I usually add the set -euo pipefail in the beginning of shell script. If I use cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c ${len} in the script, bash will raise the pipe error and exit 141. The head retrieves enough the bytes and send SIGPIPE to tr.

Is there any solution to handle this?
Thanks

@earthgecko

This comment has been minimized.

Owner

earthgecko commented Sep 15, 2016

@fufuwei try not using pipes .e.g.

len=32
head -c 256 /dev/urandom > /tmp/urandom.out
tr -dc 'a-zA-Z0-9' < /tmp/urandom.out > /tmp/urandom.tr
head -c ${len} /tmp/urandom.tr
@fuweid

This comment has been minimized.

fuweid commented Sep 16, 2016

@earthgecko cool! Thanks

@robinbowes

This comment has been minimized.

robinbowes commented Oct 4, 2016

My latest incarnation:

head -c24 < <(tr -dc '\041-\176' < /dev/urandom)

Generates a 24-char string consisting of any printable ASCII character from ! to ~.
Change 24 to whatever length you require, obviously.

@robinbowes

This comment has been minimized.

robinbowes commented Oct 5, 2016

Slight update to prevent password containing single quotes, making it easier to quote a variable containing the password.

head -c24 < <(tr --delete --complement '\041-\046\048-\176' < /dev/urandom))
@alexsorokoletov

This comment has been minimized.

alexsorokoletov commented Oct 14, 2016

This is what I ended up using in bash on OS X to have filename-safe string
cat /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | fold -w 4 | head -n 1
If you need 16 chars then use
cat /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1

You get the idea

@sora8964

This comment has been minimized.

sora8964 commented Jan 8, 2017

Thanks

@briceburg

This comment has been minimized.

briceburg commented Jan 11, 2017

@fhfuwei re: pipefail setting, you can coax it to continue as so;

set -eo pipefail
random="$(LC_CTYPE=C tr -dc 'a-zA-Z0-9-_' < /dev/urandom | head -c12)" || true

without || true at end, it will exit script.

@joviczarko

This comment has been minimized.

joviczarko commented Jan 24, 2017

Thanks! 👍

@thisolivier

This comment has been minimized.

thisolivier commented Feb 8, 2017

Fantastic work, thanks for sharing!

@jmalki

This comment has been minimized.

jmalki commented Feb 9, 2017

Strange that this command after 100 iternations only produces a + symbol. What did I do wrong?

cat /dev/urandom | base64 | tr -dc 'a-zA-Z0-9!@#$%^&*()_+?><~\;' | fold -w 16 | head -n 1`

@burningsky250

This comment has been minimized.

burningsky250 commented Apr 25, 2017

Good job! That's what I need!

@fjarrett

This comment has been minimized.

fjarrett commented May 4, 2017

To generate WordPress security keys and salts for a wp-config.php file:

# 64 random printable characters
# Excludes: space, double quote, single quote, and backslash
echo $(cat /dev/urandom | tr -dc [:print:] | tr -d '[:space:]\042\047\134' | fold -w 64 | head -n 1)
# jVig,+1&z3]}DT*$pvXPY#!z!^A-;[c0n!c*Ju=fy9`+yOauYAve<#fL]?>B9U;/

This will yield results similar to the official generator: https://api.wordpress.org/secret-key/1.1/salt/

@ManuCart

This comment has been minimized.

ManuCart commented May 11, 2017

Hi,

How de generate code like this "YH7EF",
with only one time number (nevemind where) or not and letter must differents

Thanks

@pascalandy

This comment has been minimized.

pascalandy commented May 29, 2017

Within a Docker container

LENGTH="32"

docker run --rm alpine sh -c \
"cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $LENGTH | head -n 1";
@Szero

This comment has been minimized.

Szero commented Jun 4, 2017

@ManuCart

#!/usr/bin/env bash

string=$(tr -dc '[:upper:]' < /dev/urandom | fold -w 5 | head -n 1)
if ((RANDOM % 2)); then
    sed "s/./$((RANDOM % 10))/$((RANDOM % 5 + 1))" <<< "$string"
else
    echo "$string"
fi

This will generate string with length of 5 characters, sometimes with one number in it sometimes without.

@kalyansundar

This comment has been minimized.

kalyansundar commented Jun 6, 2017

Hi,
My question is, how to allow -= those symbols..
image

@kalyansundar

This comment has been minimized.

kalyansundar commented Jun 6, 2017

I got it, how to do this

@manvedu

This comment has been minimized.

manvedu commented Jun 15, 2017

Thanks

@dpwolfe

This comment has been minimized.

dpwolfe commented Jul 5, 2017

For the simple macOS solution (currently Sierra 10.12.5), ShellCheck gives a SC2002 warning about a useless cat. I made a small modification to avoid that:

env LC_CTYPE=C tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 | head -n 1

Thank you @mihigh!

@edlugh

This comment has been minimized.

edlugh commented Jul 6, 2017

How can I create a random password with specific format.
Ex:

  1. Length 12
  2. Especial caracheres 2 or 3
  3. Number 2 or 3
  4. Lower 3+
  5. Upper 3+
@balupton

This comment has been minimized.

balupton commented Jul 20, 2017

Great, taking all the above:

env LC_CTYPE=C tr -dc 'a-z0-9' < /dev/urandom | head -c24
@JaghutTyrant

This comment has been minimized.

JaghutTyrant commented Oct 26, 2017

Many Thanks!

@zioalex

This comment has been minimized.

zioalex commented Nov 2, 2017

Thanks! Exactly what i was searching for

@ramanagak

This comment has been minimized.

ramanagak commented Dec 13, 2017

👍

@x3ak

This comment has been minimized.

x3ak commented Jan 15, 2018

Just to throw my 2 cents: dd if=/dev/urandom bs=20 count=1 2>/dev/null | openssl sha1

@carsonreinke

This comment has been minimized.

carsonreinke commented Feb 2, 2018

@x3ak, that is the best!!!

@lukas2

This comment has been minimized.

lukas2 commented Feb 7, 2018

I like

openssl rand -base64 100

or

openssl rand -hex 100

EDIT: Just noticed u2mejc posted the same earlier.

@MaRuifeng

This comment has been minimized.

MaRuifeng commented Feb 13, 2018

I use

openssl rand -base64 500 | tr -dc 'a-zA-Z0-9' | fold -w 128 | head -n 1

which generates a 128-character alphanumeric string.

@blissini

This comment has been minimized.

blissini commented Mar 8, 2018

Thanks!

@GoTeamAnt

This comment has been minimized.

GoTeamAnt commented Mar 28, 2018

A shorter version to generate a random number in hexadecimal format:

$ xxd -l16 -ps /dev/urandom
330c1515e66d01c0d695826027b513b1

Adjust the length (-l) to your liking.

@frederickjh

This comment has been minimized.

frederickjh commented May 3, 2018

1+ to @u2mejc and @lukas2 solution. This works even on very restrictive jailedshells where simple commands like tr are not available.

@oppianmatt

This comment has been minimized.

oppianmatt commented May 24, 2018

just use uuid:

cat /proc/sys/kernel/random/uuid
478b2f19-dea3-4e53-a2b1-0c6cdb5b8b29
@four43

This comment has been minimized.

four43 commented May 31, 2018

👍 To @oppianmatt for the nice simple answer. Bash function for convenience:

function random-string {
    UUID=$(cat /proc/sys/kernel/random/uuid)
    LENGTH=${1:-36}
    echo ${UUID:0:$LENGTH}
}

Output examples:

$ random-string
91f489ea-4c5a-4a14-ab89-bd028f36b242
$ random-string 8
bcbdbd1a
@rahimmohomed

This comment has been minimized.

rahimmohomed commented Jun 5, 2018

This is useful. How do I create multiple lines of random characters of fixed length and store it to a file? I am doing it this way and it prints all my 5 lines onto a single line.
for i in $(seq 1 5); do < /dev/urandom LC_CTYPE=C tr -dc "ATGC" | head -c 9 > file.txt; done

@sprig

This comment has been minimized.

sprig commented Jun 30, 2018

Depending on the usecase, this might be sufficient and easy enough to write adhoc without adding another utility to your memory
date +%s|md5 - not cryprographically secure but enough to make unique filenames.

@sprig

This comment has been minimized.

sprig commented Jun 30, 2018

Another one in similar vein that ensures you won't get the same ID if you run in quick succession:
echo "$(history)$(date +%s)"|shasum|head -c $CHARS

@joseluisq

This comment has been minimized.

joseluisq commented Sep 14, 2018

tr: Illegal byte sequence

Solution:

env LC_CTYPE=C tr -dc "A-Za-z0-9_!@#\$%^&*()-+=" < /dev/urandom | head -c 32 | xargs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment