Erlang Central

Random Numbers

Revision as of 01:47, 25 August 2006 by Cyberlync (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Problem

You want a random number from a given range. For example, you wish to randomly select one element from an array, simulate rolling a die in a game of chance, or generate a random password.

Solution

Use random:uniform function from the standard Erlang distribution. It has two forms: (1) a no-argument version that returns a random float value in the range of 0.0 to 1.0, and (2) an version that takes a single integer (N) and returns a random integer in the range of 1 to N.

1> random:uniform().
9.23009e-2
2> random:uniform(150).
67

This code generates and prints a random integer between 25 and 75, inclusive:

3> io:fwrite("Random = ~B\n", [random:uniform(51) + 24]).
Random = 74
ok

In the example, we want to limit the range to 25 to 75, so we add 24 to the result of the random:uniform function. This means we really want a random number between 1 and 51, so we give the random:uniform function the argument 51 (since the generated number is always from 1 to N).

The canonical application for this kind of number generation is the random selection of an element from a vector:

4> Dict = dict:from_list([{1,$a}, {2,$b}, {3,$c}, {4,$d}, {5,$1},
4>   {6,$2}, {7,$3}]).                                             
{dict,7,
      16,
      16,
      8,
      80,
      48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],
        [[3|99]],
        [[6|50]],
        [],
        [],
        [],
        [[2|98]],
        [[5|49]],
        [],
        [],
        [],
        [[1|97]],
        [[4|100]],
        [[7|51]],
        [],
        []}}}
5> dict:fetch(random:uniform(7), Dict).
100
6> io:fwrite("~c\n", [100]).
d
ok

Another common example is generating a random password:

generate_8_password() ->
    lists:flatten(lists:foldl(fun(X,AccIn) ->
        [random:uniform(90) + 32|AccIn] end,
        [], lists:seq(1,8))).

7> generate_8_password().
"]VD'hEa;"
8> generate_8_password().
"Zju!W9'Z"
9> generate_8_password().
"uw6uX\"JF"
10> generate_8_password().
"-)3Ue=8n"

The Erlang random number generator is attributed to B.A. Wichmann and I.D.Hill, in 'An efficient and portable pseudo-random number generator', Journal of Applied Statistics. AS183. 1982. Also Byte March 1987.

It can support bigint values, so no special recipe is required for extremely large random numbers.