Created
December 12, 2013 21:42
-
-
Save mpratt/7936062 to your computer and use it in GitHub Desktop.
A random number/range/string/bool generator
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 | |
/** | |
* Random.php | |
* | |
* @author Michael Pratt <[email protected]> | |
* @link http://www.michael-pratt.com/ | |
* @license MIT | |
* | |
*/ | |
namespace Random; | |
/** | |
* This simple class is used to generate random values | |
*/ | |
class Random | |
{ | |
/** | |
* Generates Random Bytes for the given $length. | |
* | |
* @param int $length | |
* @return string | |
* | |
* @throws InvalidArgumentException when an invalid length is specified. | |
* @throws RuntimeException when no secure way of making bytes is posible | |
*/ | |
public function bytes($length = 0) | |
{ | |
if ($length < 1) { | |
throw new \InvalidArgumentException('The lenght parameter must be a number greater than 0!'); | |
} | |
if (function_exists('openssl_random_pseudo_bytes')) { | |
$bytes = openssl_random_pseudo_bytes($length, $secure); | |
if ($secure === true) { | |
return $bytes; | |
} | |
} | |
/** | |
* There is a bug in mcrypt_create_iv in older versions/snaps of PHP in windows | |
* where an empty value is returned. | |
* https://bugs.php.net/bug.php?id=55169 | |
*/ | |
if (function_exists('mcrypt_create_iv') && (strtolower(substr(PHP_OS, 0, 3)) !== 'win' || version_compare(PHP_VERSION, '5.3.7') >= 0)) { | |
$bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); | |
if ($bytes !== false) { | |
return $bytes; | |
} | |
} | |
throw new \RuntimeException('There is no posible way of making secure bytes'); | |
} | |
/** | |
* Generates a random integer between $min and $max | |
* | |
* @param int $min | |
* @param int $max | |
* @param int $seedLenght | |
* @return int | |
* | |
* @throws InvalidArgumentException when min/max numbers are invalid | |
* @throws RuntimeException when the range is too big. | |
*/ | |
public function range($min, $max, $seedLenght = 5) | |
{ | |
if ($min >= $max) { | |
throw new \InvalidArgumentException('The min parameter must be lower than max parameter'); | |
} | |
$range = $max - $min; | |
if ($range > PHP_INT_MAX || is_float($range)) { | |
throw new \RuntimeException('The supplied range is too big'); | |
} | |
$seed = hexdec(bin2hex($this->bytes($seedLenght))); | |
while ($seed > 1) { | |
$seed *= 0.1; | |
} | |
return (int) $min + ($seed * ($range + 1)); | |
} | |
/** | |
* Generates a random string | |
* | |
* @param int $length | |
* @param string $chars If no chars are given, it uses Base64 character set. | |
* @return string | |
* | |
* @throws InvalidArgumentException when an invalid length is specified. | |
*/ | |
public function string($length = 0, $chars = null) | |
{ | |
if ($length < 1) { | |
throw new \InvalidArgumentException('The lenght parameter must be a number greater than 0!'); | |
} | |
if (empty($chars)) { | |
$numBytes = ceil($length * 0.75); | |
$bytes = $this->bytes($numBytes); | |
return substr(rtrim(base64_encode($bytes), '='), 0, $length); | |
} | |
$listLen = strlen($chars); | |
if ($listLen == 1) { | |
return str_repeat($chars, $length); | |
} | |
$bytes = $this->bytes($length); | |
$pos = 0; | |
$result = ''; | |
for ($i = 0; $i < $length; $i++) { | |
$pos = ($pos + ord($bytes[$i])) % $listLen; | |
$result .= $chars[$pos]; | |
} | |
return $result; | |
} | |
/** | |
* Generates random boolean | |
* | |
* @return bool | |
*/ | |
public function bool() | |
{ | |
return (bool) (ord($this->bytes(1)) % 2); | |
} | |
} | |
?> |
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 | |
/** | |
* @author Michael Pratt <[email protected]> | |
* @link http://www.michael-pratt.com/ | |
*/ | |
use Random\Random; | |
require 'Random.php'; | |
class TestRandom extends PHPUnit_Framework_TestCase | |
{ | |
public function testBytes() | |
{ | |
$random = new Random(); | |
$bytes1 = $random->bytes(5); | |
$bytes2 = $random->bytes(5); | |
$bytes3 = $random->bytes(5); | |
$bytes4 = $random->bytes(5); | |
$bytes5 = $random->bytes(5); | |
$bytes6 = $random->bytes(5); | |
$this->assertTrue((strlen($bytes1) == 5)); | |
$this->assertTrue((strlen($bytes2) == 5)); | |
$this->assertTrue((strlen($bytes3) == 5)); | |
$this->assertTrue((strlen($bytes4) == 5)); | |
$this->assertTrue((strlen($bytes5) == 5)); | |
$this->assertTrue((strlen($bytes6) == 5)); | |
$this->assertTrue(($bytes1 != $bytes2 && $bytes2 != $bytes3 && $bytes3 != $bytes1)); | |
$this->assertTrue(($bytes4 != $bytes5 && $bytes5 != $bytes6 && $bytes4 != $bytes6)); | |
$this->assertTrue(($bytes1 != $bytes6 && $bytes1 != $bytes4 && $bytes5 != $bytes1)); | |
$this->assertTrue(($bytes2 != $bytes6 && $bytes2 != $bytes4 && $bytes5 != $bytes2)); | |
$this->assertTrue(($bytes3 != $bytes6 && $bytes3 != $bytes4 && $bytes5 != $bytes3)); | |
} | |
public function testBytesInvalid() | |
{ | |
$this->setExpectedException('InvalidArgumentException'); | |
$random = new Random(); | |
$bytes1 = $random->bytes(); | |
} | |
public function testRange() | |
{ | |
$random = new Random(); | |
$r1 = $random->range(5, 25); | |
$r2 = $random->range(5, 25); | |
$r3 = $random->range(5, 25); | |
$this->assertTrue(($r1 != $r2 && $r2 != $r3 && $r3 != $r1)); | |
$this->assertTrue(($r1 >= 5 && $r1 <= 25)); | |
$this->assertTrue(($r2 >= 5 && $r2 <= 25)); | |
$this->assertTrue(($r3 >= 5 && $r3 <= 25)); | |
} | |
public function testRange2() | |
{ | |
$random = new Random(); | |
$r1 = $random->range(5, 200); | |
$r2 = $random->range(5, 200); | |
$r3 = $random->range(5, 200); | |
$this->assertTrue(($r1 != $r2 && $r2 != $r3 && $r3 != $r1)); | |
$this->assertTrue(($r1 >= 5 && $r1 <= 200)); | |
$this->assertTrue(($r2 >= 5 && $r2 <= 200)); | |
$this->assertTrue(($r3 >= 5 && $r3 <= 200)); | |
} | |
public function testRangeInvalid() | |
{ | |
$this->setExpectedException('InvalidArgumentException'); | |
$random = new Random(); | |
$random->range(10, 5); | |
} | |
public function testBool() | |
{ | |
$random = new Random(); | |
$this->assertTrue(is_bool($random->bool())); | |
$this->assertTrue(is_bool($random->bool())); | |
$this->assertTrue(is_bool($random->bool())); | |
$this->assertTrue(is_bool($random->bool())); | |
$this->assertTrue(is_bool($random->bool())); | |
$this->assertTrue(is_bool($random->bool())); | |
$this->assertTrue(is_bool($random->bool())); | |
} | |
public function testString() | |
{ | |
$random = new Random(); | |
$s1 = $random->string(4); | |
$s2 = $random->string(4); | |
$s3 = $random->string(4); | |
$this->assertTrue(($s1 != $s2 && $s2 != $s3 && $s3 != $s1)); | |
$this->assertEquals(strlen($s1), 4); | |
$this->assertEquals(strlen($s2), 4); | |
$this->assertEquals(strlen($s3), 4); | |
$this->assertTrue(is_string($s1)); | |
$this->assertTrue(is_string($s2)); | |
$this->assertTrue(is_string($s3)); | |
} | |
public function testStringChars() | |
{ | |
$random = new Random(); | |
$chars = 'aGhretdPxZmlL046s1r'; | |
$s1 = $random->string(4, $chars); | |
$s2 = $random->string(4, $chars); | |
$s3 = $random->string(4, $chars); | |
$this->assertTrue(($s1 != $s2 && $s2 != $s3 && $s3 != $s1)); | |
$this->assertEquals(strlen($s1), 4); | |
$this->assertEquals(strlen($s2), 4); | |
$this->assertEquals(strlen($s3), 4); | |
$this->assertTrue(is_string($s1)); | |
$this->assertTrue(is_string($s2)); | |
$this->assertTrue(is_string($s3)); | |
$this->assertTrue((strpos('u', $s1) === false)); | |
$this->assertTrue((strpos('u', $s2) === false)); | |
$this->assertTrue((strpos('u', $s3) === false)); | |
} | |
public function testStringInvalid() | |
{ | |
$this->setExpectedException('InvalidArgumentException'); | |
$random = new Random(); | |
$random->string(); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment