Version 11 of random

Updated 2009-06-21 12:15:16 by dkf

PT - This is a package that provides alternative pseudo-random number generators.

mt_rand() is based upon the Mersenne Twister PRNG algorithm ([L1 ], [L2 ]). This PRNG has an enormous period (in fact it is 2**19937-1 which is a Mersenne Prime, hence the name). It is also supposedly faster than the standard C library rand() function. Furthermore, while the stock Tcl rand function generates numbers in the range (0,1), randmt produces numbers in the range [0,1]. If required, it can also produce values within (0,1) as well as integer values (any 32bit value)

isaac_rand() uses the ISAAC algorithm [L3 ] by Bob Jenkins. ISAAC (Indirection, Shift, Accumulate, Add, and Count) generates 32-bit random numbers. The period is guaranteed to be at least 2**40 and is 2**8295 on average. The results are uniformly distributed, unbiased, and unpredictable unless you know the seed. This PRNG is suitable for cryptographic use provided a suitably random seed can be provided.

sub_rand() is a subtractive random number generator. See Knuth, D.E. 1981, "Seminumerical Algorithms" 2nd ed. vol 2 of "The Art of Computer Programming" para: 3.2-3.3.

For each of these PRNGs a command in the random namespace exists to provide extended access. Currently the subcommands are integer, double, seed and state which provide an integer or double random number (the expr function always provides a double). The seed subcommand lets you seed the generator with a byte array, for example an array obtained from /dev/random. The statesubcommand returns a byte array that contains the current state of the generator. This could be used to seed the next instance of a generator.

Currently the code is available at

 cvs -d:pserver:[email protected]:/cvsroot/tclsoap co Random

and the distributable files are at in the downloads section.


  package require Random

  # Seed and use the Mersenne Twister PRNG
  % expr {mt_srand(0)}
  % expr {mt_rand()}

  # Seed and use the ISAAC PRNG
  % expr {isaac_srand(0)}
  % expr {isaac_rand()}

  # Subtractive PRNG
  % expr {sub_srand(0)}
  % expr {sub_rand()}

  # Extended ISAAC commands
  # Provide extra seed data (up to 256 values can be used)
  % ::random::isaac seed "\x01\x02\x03\x04\x05"

  # Get integers from the PRNG (must have been seeded already)
  % ::random::isaac integer

  # Get doubles (equivalent to the expr function)
  % ::random::isaac double

  # Extended subtractive PRNG commands
  % random::subtractive seed [string repeat \x00 3000]
  % random::subtractive integer
  % string length [random::subtractive state]

schlenk A little example generating random passwords with the help of the isaac generator:

 proc createPassword {{minlen 15}} {
        set chars [split {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890?:!%$*} ""]
        set len [llength $chars]

        set pw ""
        while {[string length $pw] < $minlen} {        
                set rand [::random::isaac integer]
                while {$rand > 0 && $minlen && [string length $pw] < $minlen} {
                        set rest [expr {$rand % $len}]
                        set rand [expr {$rand / $len}]
                        append pw [lindex $chars $rest] 
        return $pw

random is also one of TclX Commands.

random limit

Return a random integer that is uniformly distributed over the range from 0 to one less than limit.

random seed ?seedval?

Reseed the random number generator with seedval, or a value based on the current system time if seedval is omitted.