2.6. Generating Random Numbers
2.6.1. Problem
You
want to make random numbers in a given range, inclusive, such as when
you randomly pick an array index, simulate rolling a die in a game of
chance, or generate a random password.
2.6.2. Solution
Use Perl's
rand function:
$random = int( rand( $Y-$X+1 ) ) + $X;
2.6.3. Discussion
This code generates and prints a random integer between 25 and 75,
inclusive:
$random = int( rand(51)) + 25;
print "$random\n";
The rand function returns a fractional number,
from (and including) 0 up to (but not including) its argument. We
give it an argument of 51 to get a number that can be 0 or more, but
never 51 or more. We take the integer portion of this to get a number
from 0 to 50, inclusive (50.99999.... will be turned into 50 by
int). We then add 25 to it to get a number from 25
to 75, inclusive.A common application of this is the
random selection of an element from an array:
$elt = $array[ rand @array ];
That's just like saying:
$elt = $array[ int( rand(0+@array) ) ];
Because rand is prototyped to take just one
argument, it implicitly imposes scalar context on that argument,
which, on a named array, is the number of elements in that array. The
function then returns a floating-point number smaller than its
argument and greater than or equal to zero. A floating-point number
used as an array subscript implicitly undergoes integer truncation
(rounding toward zero), producing in the end an evenly distributed,
randomly selected array element to assign to $elt.Generating a random password from a
sequence of characters is similarly easy:
@chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ & *) );
$password = join(", @chars[ map { rand @chars } ( 1 .. 8 ) ]);
We use map to generate eight random indices into
@chars, extract the corresponding characters with
a slice, and join them together to form the random password. This
isn't a good random number, though, as its
security relies on the choice of seed, which (in older versions of
Perl) is based on the time the program started. See Recipe 2.7 for a way to better seed your random number
generator.
2.6.4. See Also
The int, rand,
map, and join functions in
perlfunc(1) and Chapter 29 of
Programming Perl; we explore random numbers
further in Recipe 2.7, Recipe 2.8, and Recipe 2.9; we use
random numbers in Recipe 1.13