``````package Math::Random::MT;

use strict;
use Carp;
use vars qw( @ISA \$VERSION );

my \$gen = undef;
\$VERSION = '1.17';

bootstrap Math::Random::MT \$VERSION;

sub new
{
my (\$class, @seeds) = @_;

my \$self = Math::Random::MT::init();
\$self->set_seed(@seeds);

return \$self;
}

sub set_seed
{
my (\$self, @seeds) = @_;
@seeds > 1 ? \$self->setup_array(@seeds) :
\$self->init_seed(defined \$seeds[0] ? \$seeds[0] : _rand_seed());
return \$self->get_seed;
}

sub srand
{
my (@seeds) = @_;
\$gen = Math::Random::MT->new(@seeds);
return \$gen->get_seed;
}

sub rand
{
my (\$self, \$N) = @_;

unless (ref \$self) {
\$N = \$self;
Math::Random::MT::srand() unless defined \$gen;
\$self = \$gen;
}

return (\$N || 1) * \$self->genrand();
}

sub irand
{
my (\$self) = @_;

unless (ref \$self) {
Math::Random::MT::srand() unless defined \$gen;
\$self = \$gen;
}

return \$self->genirand();
}

# Generate a random seed using the built-in PRNG.

sub _rand_seed {
my (\$self) = @_;

# Get a seed at random through Perl's CORE::rand(). We do not call
# CORE::srand() to avoid altering the random numbers that other parts of
# the running script might be using. The seeds obtained by rapid calls to
# the _rand_seed() function are all different.

return int(CORE::rand(2**32));
}

sub import
{
no strict 'refs';
my \$pkg = caller;
foreach my \$sym (@_) {
if (\$sym eq 'srand' || \$sym eq 'rand' || \$sym eq 'irand') {
*{"\${pkg}::\$sym"} = \&\$sym;
}
}
}

1;

__END__

Math::Random::MT - The Mersenne Twister PRNG

## Object-oriented interface:
use Math::Random::MT;
\$gen = Math::Random::MT->new()        # or...
\$gen = Math::Random::MT->new(\$seed);  # or...
\$gen = Math::Random::MT->new(@seeds);
\$seed = \$gen->get_seed();             # seed used to generate the random numbers
\$rand = \$gen->rand(42);               # random number in the interval [0, 42)
\$dice = int(\$gen->rand(6)+1);         # random integer between 1 and 6
\$coin = \$gen->rand() < 0.5 ?          # flip a coin
\$int = \$gen->irand();                 # random integer in [0, 2^32-1]

## Function-oriented interface:
use Math::Random::MT qw(srand rand irand);
# now use srand() and rand() as you usually do in Perl

The Mersenne Twister is a pseudorandom number generator developed by
Makoto Matsumoto and Takuji Nishimura. It is described in their paper at
<URL:http://www.math.keio.ac.jp/~nisimura/random/doc/mt.ps>. This algorithm
has a very uniform distribution and is good for modelling purposes but do not
use it for cryptography.

This module implements two interfaces:

=over

=item new()

Creates a new generator that is automatically seeded based on gettimeofday.

=item new(\$seed)

Creates a new generator seeded with an unsigned 32-bit integer.

=item new(@seeds)

Creates a new generator seeded with an array of (up to 624) unsigned
32-bit integers.

=item set_seed()

Seeds the generator and returns the seed used. It takes the same arguments as
I<new()>.

=item get_seed()

Retrieves the value of the seed used.

=item rand(\$num)

Behaves exactly like Perl's builtin rand(), returning a number uniformly
distributed in [0, \$num) (\$num defaults to 1).

=item irand()

Returns a 32-bit integer, i.e. an integer uniformly distributed in [0, 2^32-1].

=back

=over

=item srand(\$seed)

Behaves just like Perl's builtin srand(). As in Perl >= 5.14, the seed is
returned. If you use this interface, it is strongly recommended that you
call I<srand()> explicitly, rather than relying on I<rand()> to call it the
first time it is used.

=item rand(\$num)

Behaves exactly like Perl's builtin rand(), returning a number uniformly
distributed in [0, \$num) (\$num defaults to 1).

=item irand()

Returns a 32-bit integer, i.e. an integer uniformly distributed in [0, 2^32-1].

=back

<URL:http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>

Data::Entropy

=over 4

=item Sean M. Burke

For giving me the idea to write this module.

=item Philip Newton

For several useful patches.

=item Florent Angly

For implementing seed generation and retrieval.

=back