Source of kr_prng.php
<?php
/*
* PHP implementation of Kernighan and Ritchie's example
* pseudorandom number generator.
*
* By Matthew Kerwin, 2009.
*
* Based on: http://computer.howstuffworks.com/question697.htm
*/
class kr_uint32 {
private $words = array(0, 0);
public function __construct($value = 0) {
if (is_a($value, 'kr_uint32')) {
$this->words[0] = $value->words[0];
$this->words[1] = $value->words[1];
} else {
$value = intval($value);
if ($value) {
if ($negative = ($value < 0)) $value = -$value;
$this->words[0] = $value & 0xFFFF;
$this->words[1] = ($value >> 16) & 0xFFFF;
if ($negative) $this->_negate();
}
}
}
public function to_string($pad=false) {
$s = sprintf("%04X%04X", $this->words[1], $this->words[0]);
if (!$pad) {
$s = preg_replace('/^0+/', '', $s);
if (!$s) $s = '0';
}
return $s;
}
public function to_int() {
return $this->words[0] + ($this->words[1] * 0x10000);
}
public function hi_word() {
return $this->words[1];
}
public function lo_word() {
return $this->words[0];
}
/**
* One's complement negation.
*/
public function _not() {
$this->words[0] = ~$this->words[0] & 0xFFFF;
$this->words[1] = ~$this->words[1] & 0xFFFF;
}
/**
* Two's complement negation.
*/
public function _negate() {
$this->_not();
$this->_add(1);
}
/**
* Adds a uint32 value to this number.
*/
public function _add($x) {
if (!is_a($x, 'kr_uint32')) {
$x = new kr_uint32($x);
}
$r = 0;
for ($i = 0; $i < 2; $i++) {
$w = $this->words[$i] + $x->words[$i] + $r;
$this->words[$i] = $w & 0xFFFF;
$r = $w >> 16;
}
}
/**
* Multiplies a uint32 value by this number.
*/
public function _times($x) {
if (is_a($x, 'kr_uint32')) {
$a = $this->words[0] * $x->words[0];
$b = $this->words[0] * $x->words[1] * 0x10000;
$c = $this->words[1] * $x->words[0] * 0x10000;
# note: ignore [1] * [1] * 0x100000000, because it overflows anyway
$n = $a + $b + $c;
} else {
$x = intval($x);
$a = $this->words[0] * $x;
$b = $this->words[1] * $x * 0x10000;
$n = $a + $b;
}
$this->words[0] = $n & 0xFFFF;
$this->words[1] = ($n >> 16) & 0xFFFF;
}
}
function kr_srand($seed) {
$GLOBALS['kr_random_seed'] = new kr_uint32($seed);
}
function kr_rand($min = 0, $max = 32768) {
if (!isset($GLOBALS['kr_random_seed']) || !is_a($GLOBALS['kr_random_seed'], 'kr_uint32')) {
kr_srand(mt_rand());
}
$GLOBALS['kr_random_seed']->_times(1103515245);
$GLOBALS['kr_random_seed']->_add(12345);
return ($GLOBALS['kr_random_seed']->hi_word() % ($max - $min)) + $min;
}