-
-
Save CodesInChaos/03f9ea0b58e8b2b8d435 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if (!function_exists('random_bytes')) { | |
function random_bytes($size) | |
{ | |
if(!is_int($size)) | |
throw new Exception('random_bytes: $size must be an int'); | |
if($size <= 0) | |
throw new Exception('random_bytes: $size must be positive'); | |
if(function_exists('mcrypt_create_iv')) | |
{ | |
$result = mcrypt_create_iv($size, MCRYPT_DEV_URANDOM); | |
} | |
else if(function_exists('openssl_random_pseudo_bytes')) | |
{ | |
$result = openssl_random_pseudo_bytes($size, $isSecure); | |
if($isSecure !== true) | |
{ | |
throw new Exception("random_bytes: openssl_random_pseudo_bytes returned insecure data"); | |
} | |
} | |
else | |
{ | |
throw new Exception("random_bytes: No RNG found"); | |
} | |
if(!is_string($result) || (strlen($result) !== $size)) | |
{ | |
throw new Exception("random_bytes: RNG is unavailable or broken"); | |
} | |
return $result; | |
} | |
} | |
if (!function_exists('random_int')) { | |
function random_int($min, $max) | |
{ | |
if(version_compare(PHP_VERSION, '5.1.0') < 0) | |
trigger_error("random_int: This version of PHP is not supported", E_USER_ERROR); | |
if(!is_int($min)) | |
throw new Exception('random_int: $min must be an int'); | |
if(!is_int($max)) | |
throw new Exception('random_int: $max must be an int'); | |
if($min > $max) | |
throw new Exception('random_int: $min must be less or equal to $max'); | |
$range = $max - $min + 1; | |
// the rejection probability is at most 0.5, so this corresponds to a failure probability of 2^-128 for a working RNG | |
for($attempts = 0; $attempts < 128; $attempts++) | |
{ | |
// generate a random integer | |
$bytes = random_bytes(PHP_INT_SIZE); | |
$value = 0; | |
for($i = 0; $i < PHP_INT_SIZE; $i++) | |
{ | |
$value = ($value << 8) | ord($bytes[$i]); | |
} | |
if(!is_int($range)) | |
{ | |
if(($value >= $min) && ($value <= $max)) | |
{ | |
return $value; | |
} | |
} else { | |
$value &= PHP_INT_MAX; | |
// equivalent to (PHP_INT_MAX + 1) % range, but avoids int overflows | |
// I'm assuming PHP_INT_MAX + 1 is a power-of-two and that integer's are represented as two's complement. | |
$reject = (-$range & PHP_INT_MAX) % $range; | |
if($value >= $reject) | |
{ | |
return ($value % $range) + $min; | |
} | |
} | |
} | |
throw new Exception("random_int: RNG is broken - too many rejections"); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if (!function_exists('random_string')) { | |
function random_string($length, $charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") | |
{ | |
if(!is_int($length)) | |
throw new Exception('random_string: $length must be an integer'); | |
if($length < 1) | |
throw new Exception('random_string: $length must be positive'); | |
if(!is_string($charset)) | |
throw new Exception('random_string: $charset must be a string'); | |
if(strlen($charset) < 1) | |
throw new Exception('random_string: $charset must contain at least one element'); | |
$randomString = ""; | |
for ($i = 0; $i < $length; $i++) | |
$randomString .= $charset[random_int(0, strlen($charset) - 1)]; | |
return $randomString; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment