Skip to content

Commit

Permalink
Merge 14afeac into 296cd31
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergii Pavlenko committed Jan 10, 2019
2 parents 296cd31 + 14afeac commit ac793ba
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/Generator/CSPRNGenerator.php
@@ -0,0 +1,76 @@
<?php
/**
* Ryan's Random Data Library
*
* @package Rych\Random
* @author Ryan Chouinard <rchouinard@gmail.com>
* @copyright Copyright (c) 2013, Ryan Chouinard
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/

namespace Rych\Random\Generator;

/**
* Cryptographically secure pseudo-random number generator
*
* The cryptographically secure pseudo-random number generator (CSPRNG) API
* provides an easy and reliable way to generate crypto-strong random integers
* and bytes for use within cryptographic contexts.
*
* @package Rych\Random
* @author Ryan Chouinard <rchouinard@gmail.com>
* @copyright Copyright (c) 2013, Ryan Chouinard
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/
class CSPRNGenerator implements GeneratorInterface
{

/**
* Generate a string of random data.
*
* @param integer $byteCount The desired number of bytes.
* @return string Returns the generated string.
*/
public function generate($byteCount)
{
$bytes = '';

if (self::isSupported()) {
$mcryptStr = random_bytes($byteCount);
if ($mcryptStr !== false) {
$bytes = $mcryptStr;
}
}

return str_pad($bytes, $byteCount, chr(0));
}

/**
* Test system support for this generator.
*
* @return boolean Returns true if the generator is supported on the current
* platform, otherwise false.
*/
public static function isSupported()
{
$supported = false;
if (function_exists('random_bytes') &&
version_compare(phpversion(), '7.1', '>=')) {
$supported = true;
}

return $supported;
}

/**
* Get the generator priority.
*
* @return integer Returns an integer indicating the priority of the
* generator. Lower numbers represent lower priorities.
*/
public static function getPriority()
{
return GeneratorInterface::PRIORITY_HIGH;
}

}
64 changes: 64 additions & 0 deletions tests/Generator/CSPRNGeneratorTest.php
@@ -0,0 +1,64 @@
<?php
/**
* Ryan's Random Data Library
*
* @package Rych\Random
* @author Ryan Chouinard <rchouinard@gmail.com>
* @copyright Copyright (c) 2013, Ryan Chouinard
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/

namespace Rych\Random\Tests\Generator;

use Rych\Random\Generator\CSPRNGenerator;
use PHPUnit_Framework_TestCase as TestCase;

/**
* CSPRN generator tests
*
* @package Rych\Random
* @author Ryan Chouinard <rchouinard@gmail.com>
* @copyright Copyright (c) 2013, Ryan Chouinard
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*/
class CSPRNGeneratorTest extends TestCase
{

/**
* @return void
*/
protected function setUp()
{
if (!CSPRNGenerator::isSupported()) {
$this->markTestSkipped('CSPRNG is not supported on this platform.');
}
}

/**
* @test
* @return void
*/
public function testGenerateMethodProducesVaryingResultsEachCall()
{
$generator = new CSPRNGenerator;
$previous = array ();
for ($i = 0; $i < 10; ++$i) {
$result = $generator->generate(8);
$this->assertTrue(strlen($result) === 8, 'Generator should produce a string length of eight.');
$this->assertFalse(in_array($result, $previous), 'Generator should not duplicate a previous result in subsequent calls.');
$previous[] = $result;
}
}

/**
* @test
* @return void
*/
public function testGetPriorityMethodReturnsInteger()
{
$this->assertInternalType('integer', CSPRNGenerator::getPriority(), 'Generator should express priority as an integer value.');
$this->assertTrue(0 < CSPRNGenerator::getPriority() && 4 > CSPRNGenerator::getPriority(), 'Generator should have a priority between 1 and 3.');
}

}

0 comments on commit ac793ba

Please sign in to comment.