Bash Shell Generate Random Numbers

by on April 27, 2010 · 15 comments· LAST UPDATED April 27, 2010

in

How do I create or generate random numbers (sequence of numbers that lack any pattern), under Bash shell?

The bash shell offers $RANDOM variable (it also works with ksh). From the bash man page:

Each time this is referenced, a random integer between 0 and 32767 is generated. The sequence of random numbers may be initialized by assigning a value to RANDOM. If RANDOM is unset, it loses its special properties, even if it is subsequently reset.

To view $RANDOM, enter:
$ echo $RANDOM
Sample outputs:

11799

You can use the bash loop as follows to test random numbers:

for i in {1..5}; do echo $RANDOM; done

Sample outputs:

32340
18591
32100
15165
19743

You can store it to a variable as follows:

#!/bin/bash
 n=$RANDOM
 echo "My move: trying $n..."
 

You can have a random integer number within a certain range as follows:

 
n=$RANDOM
# display a random integer <= 200
echo $(( r %= 200 ))
# display random number between 100 and 200.
echo $((RANDOM%200+100))
 

Here is a sample shell script to find out random TCP port:

#!/bin/bash
# Set a trap to detect spam bots at port 80
 
# Find out random unused TCP port 
findRandomTcpPort(){
	port=$(( 100+( $(od -An -N2 -i /dev/random) )%(1023+1) ))
	while :
	do
		(echo >/dev/tcp/localhost/$port) &>/dev/null &&  port=$(( 100+( $(od -An -N2 -i /dev/random) )%(1023+1) )) || break
	done
	echo "$port"
}
 
p=$(findRandomTcpPort)
echo "Setting Honeypot @ port 80 and real Apache server at port $p..."
# setHoneypot 80 
# setApache $p
 

Another shell script to setup a random wallpaper. You can call this one from your crontab:

#!/bin/bash
# get images
files=(/nas/download/share/fun/images/wallpapers/*.png)
# find out random one
n=${#files[@]}           
wallpaper="${files[RANDOM % n]}"
# Kde3 command (may not work with kde4)
# dcop kdesktop KBackgroundIface setWallpaper "$wallpaper" 5
 
# Gnome command
gconftool-2 --type string --set /desktop/gnome/background/picture_filename "$wallpaper"

Using /dev/urandom or /dev/random

The character special files /dev/random and /dev/urandom provide an interface to the kernel's random number generator. You can use /dev/urandom as follows:
$ od -vAn -N4 -tu4 < /dev/urandom
Sample outputs:

2494028411

You can use /dev/random as follows:
$ od -An -N2 -i /dev/random
Sample outputs:

62362

Recommended readings:

See the following man pages:
man 4 random
man bash
man od

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 15 comments… read them below or add one }

1 Deluxe April 27, 2010 at 11:59 pm

Thanks for the tips. Two mistake though:
– ‘echo $(( r %= 200 ))’ should be ‘echo $(( n %= 200 ))’
– ‘echo $((RANDOM%200+100))’ return a number between 100 and 300, not 100 and 200 as commented above.

Reply

2 Philippe Petrinko April 28, 2010 at 1:37 pm

Nice topic.
Precision:

echo $(( n %= 200 ))

Will return an integer strictly less than 200.

I think that If you want to include 200, you could use:

echo $(( n %= 200 + 1))

But then, [n] will never be zero, it will belong to [1;200]

Reply

3 Philippe Petrinko April 28, 2010 at 1:39 pm

Then if you want a random integer belonging to [0;200],
you may use:

echo $(( n %= 201))

Reply

4 Paul Dubuc April 30, 2010 at 2:31 pm

Like the man page excerpt above says, you can initialize the sequence by assigning an arbitrary number to RANDOM before using it. If you don’t want the same ‘random’ sequence each time you run the script, you should seed RANDOM by assigning an arbitrary number before using it. The process ID works well:

RANDOM=$$

Reply

5 Erik May 10, 2010 at 7:06 pm

OpenSSL can also be used as a source of random numbers, and is a good idea if the numbers are going to be used for cryptographic key generation or nonces. The generator used by OpenSSL uses a FIPS 140 approved algorithm and has been widely tested and reviewed.

OpenSSL on Unix systems will leverage available entropy from the OS RNG as part of it’s seed/start process.

Here are some sample commands – quoted from the “OpenSSL Command-line HOWTO”:

# write 128 random bytes of base64-encoded data to stdout
openssl rand -base64 128

# write 1024 bytes of binary random data to a file
openssl rand -out random-data.bin 1024

Cheers, Erik
ArtofInfoSec.com

Reply

6 Mark Szymanski August 27, 2010 at 1:46 am

Is there any way to do this with a custom random seed?

Reply

7 Philippe Petrinko August 27, 2010 at 7:32 am

vivek,
There is a bug here:

# display random number between 100 and 200.
echo $((RANDOM%200+100))

This will display random number between 100 and 300 (not 200)

If you want to display random number between 100 and 200, use:

echo $((RANDOM%100+100))

Would you modify yor code above?

Reply

8 ravi July 27, 2011 at 5:43 am

really nice

Reply

9 Dago February 12, 2012 at 5:47 pm

#Bug in ‘display random number between 100 and 200.’
echo $((RANDOM%200+100))

#For determine the random number between x and y is:
echo $((x + RANDOM%(y-x+1)))

Reply

10 Zdendo March 20, 2012 at 1:08 am

Works good:
echo $(( RANDOM% ($maximal – $minimal) + $minimal ))

example: maximal=10 minimal=5 try it ;)

Or if you want numbers between 5 – 10, you can do this:
echo $(( RANDOM% 5 + 5 ))
5 – minimum, maximum is +5 bigger

Reply

11 Philippe Petrinko March 20, 2012 at 9:26 am

Hi Vivek,

You may be overwhelmed or overloaded,
but you will also find that this page does not meet your quality standard.

1) As Dago said:
#To get random integer number between x and y, x and y beeing included as in [x;y] notation, use:
echo $((x + RANDOM%(y-x+1)))

2) Typo
There is still a typo here: echo $(( r %= 200 ))
Should be: echo $(( n %= 200 ))

3) Misunderstanding
Why do you use “%=” where “%” will be appropriate ?
That is: echo $(( n %= 200 ))
Should be: echo $(( n % 200 ))

KUTGW, I really appreciate your site – as usual, great work.

— Philippe

Reply

12 Satish June 4, 2012 at 12:51 pm

Hi
that was useful, didn’t know there was more than one method to generate random number.

Reply

13 ksaver August 29, 2012 at 7:20 pm

Nice and instructive post!
I was looking for a way to seed the $RANDOM-ness in bash, and I found this can be done by setting the $RANDOM variable:
$ RANDOM=1
$ echo $RANDOM
16807
$ echo $RANDOM
15089
$ RANDOM=1
$ echo $RANDOM
16807
$ echo $RANDOM
15089

May be a good way for seeding randomness would be using time:
$ RANDOM=$(date +%s)

Thanks a lot!

Reply

14 none February 2, 2013 at 6:16 am

in a simplest exposure:
$((RANDOM%offsetFromLowest+Lowest))

Reply

15 Roel May 9, 2014 at 3:20 am

Nanosecond semi-random number generator

date +’%N’

Can also be used as $RANDOM shuffler:

RANDOM=$(date +’%N’)

$ RANDOM=$(date +’%N’)
$ echo $RANDOM
13967
$ RANDOM=$(date +’%N’)
$ echo $RANDOM
27211

Reply

Leave a Comment

Tagged as: , , , , , , , , ,

Previous Faq:

Next Faq: