Skip to content

Instantly share code, notes, and snippets.

@natmchugh
Last active November 11, 2015 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natmchugh/064ca5b6baae4cac734e to your computer and use it in GitHub Desktop.
Save natmchugh/064ca5b6baae4cac734e to your computer and use it in GitHub Desktop.
A MersenneTwister implementation that gives the same values as PHP's internal value
<?php
class MersenneTwister
{
// Create a length 624 array to store the state of the generator
private $MT;
private $index;
public function __construct($seed)
{
$this->initialize_generator($seed);
}
public function setInternalState($state, $index)
{
$this->MT = $state;
$this->index = $index;
}
// Initialize the generator from a seed
function initialize_generator($seed) {
$this->MT = new \SplFixedArray(624);
$this->index = 0;
$this->MT[0] = $seed;
for ($i = 1; $i < 624; $i++) { // loop over each other element
$this->MT[$i] = (0x6c078965 * ($this->MT[$i-1] ^ ($this->MT[$i-1] >> 30)) + $i) & 0xffffffff;// 0x6c078965
}
}
// Extract a tempered pseudorandom number based on the index-th value,
// calling generate_numbers() every 624 numbers
function extract_number() {
if ($this->index == 0) {
$this->generate_numbers();
}
$y = $this->MT[$this->index];
$y = $y ^ ($y >> 11);
$y = $y ^ (($y << 7) & 0x9d2c5680); // 0x9d2c5680
$y = $y ^ (($y << 15) & 0xefc60000); // 0xefc60000
$y = $y ^ ($y >> 18);
$this->index = ($this->index + 1) % 624;
return $y >> 1;
}
// Generate an array of 624 untempered numbers
function generate_numbers() {
foreach ($this->MT as $i => $mt) {
$z = $mt;
$y = ($mt & 0x80000000) + ($this->MT[($i+1) % 624] & 0x7fffffff); // bits 0-30 (first 31 bits) of MT[...]
$this->MT[$i] = $this->MT[(($i + 397) % 624)] ^ ($y >> 1);
if (($z % 2) != 0) { // z is odd
$this->MT[$i] ^= 0x9908b0df;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment