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(00);

    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;
}