. */ namespace Volkszaehler\Util; /** * Extensible PRNG * * @author Steffen Vogel * @package util */ class Random { protected static $func = NULL; protected static $source = NULL; /** * Initialize the PRNG * * Look for a system-provided source of randomness, which is usually crytographically secure. * /dev/urandom is tried first simply out of bias for Linux systems. */ public static function init() { if (is_readable('/dev/urandom')) { self::$source = fopen('/dev/urandom', 'rb'); self::$func = 'fRead'; } elseif (class_exists('COM', 0)) { try { self::$source = new COM('CAPICOM.Utilities.1'); // See http://msdn.microsoft.com/en-us/library/aa388182(VS.85).aspx self::$func = 'COM'; } catch(\Exception $e) {} } else { self::$func = 'twister'; } return self::$func; } /** * * @param intger $bytes */ public static function getBytes($count) { if (!isset(self::$func)) { self::init(); } return call_user_func(array('self', self::$func), $count); } /** * * @param array $chars charset for random string * @param integer $count length of string */ public function getString(array $chars, $length) { $numbers = self::getNumbers(0, count($chars) - 1, $length); $string = ''; foreach ($numbers as $number) { $string .= $chars[$number]; } return $string; } /** * Generate $count random numbers between $min and $max * * @param integer $min * @param integer $max * @param integer $count * @return integer|array single integer if $count == 1 or array of integers if $count > 1 */ public static function getNumbers($min, $max, $count = 1) { $bytes = self::getBytes($count); $numbers = array(); for ($i = 0; $i < $count; $i++) { $numbers[] = ord($bytes[$i]) % ($max - $min + 1) + $min; } return ($count == 1) ? $numbers[0] : $numbers; } /* * Get the specified number of random bytes, using mt_rand(). * Randomness is returned as a string of bytes. */ protected static function twister($count) { $rand = ''; for ($a = 0; $a < $count; $a++) { $rand .= chr(mt_rand(0, 255)); } return $rand; } /** * Get the specified number of random bytes using a file handle * previously opened with Random::init(). * Randomness is returned as a string of bytes. */ protected static function fRead($count) { return fread(self::$source, $count); } /* * Get the specified number of random bytes using Windows' * randomness source via a COM object previously created by Random::init(). * Randomness is returned as a string of bytes. */ protected static function COM($count) { return base64_decode(self::$source->GetRandom($count, 0)); // straight binary mysteriously doesn't work, hence the base64 } } ?>