Add Symfony Deprecation Contracts package
- Created CHANGELOG.md to maintain version history. - Added README.md with usage instructions for the trigger_deprecation() function. - Initialized composer.json for the Symfony Deprecation Contracts library, specifying dependencies and autoloading.
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* The RandomLib library for securely generating random numbers and strings in PHP
|
||||
*
|
||||
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
|
||||
* @copyright 2011 The Authors
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version Build @@version@@
|
||||
*/
|
||||
|
||||
use RandomLib\Generator;
|
||||
use RandomLibTest\Mocks\Random\Mixer;
|
||||
use RandomLibTest\Mocks\Random\Source;
|
||||
|
||||
class Vectors_Random_GeneratorTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public static function provideGenerateInt()
|
||||
{
|
||||
return array(
|
||||
// First, lets test each offset based range
|
||||
array(0, 7),
|
||||
array(0, 15),
|
||||
array(0, 31),
|
||||
array(0, 63),
|
||||
array(0, 127),
|
||||
array(0, 255),
|
||||
array(0, 511),
|
||||
array(0, 1023),
|
||||
// Let's try a range not starting at 0
|
||||
array(8, 15),
|
||||
// Let's try a range with a negative number
|
||||
array(-18, -11),
|
||||
// Let's try a non-power-of-2 range
|
||||
array(10, 100),
|
||||
// Finally, let's try two large numbers
|
||||
array(100000, 100007),
|
||||
array(100000000, 100002047),
|
||||
// Now, let's force a few loops by setting a valid offset
|
||||
array(0, 5, 2),
|
||||
array(0, 9, 5),
|
||||
array(0, 27, 4),
|
||||
);
|
||||
}
|
||||
|
||||
public static function provideGenerators()
|
||||
{
|
||||
$factory = new \RandomLib\Factory();
|
||||
$generator = $factory->getLowStrengthGenerator();
|
||||
$sources = $generator->getSources();
|
||||
$ret = array();
|
||||
|
||||
$ret[] = array(new Generator($sources, new \RandomLib\Mixer\Hash()), 10000, 'hash');
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test asserts that the algorithm that generates the integers does not
|
||||
* actually introduce any bias into the generated numbers. If this test
|
||||
* passes, the generated integers from the generator will be as unbiased as
|
||||
* the sources that provide the data.
|
||||
*
|
||||
* @dataProvider provideGenerateInt
|
||||
*/
|
||||
public function testGenerateInt($min, $max, $offset = 0)
|
||||
{
|
||||
$generator = $this->getGenerator($max - $min + $offset);
|
||||
for ($i = $max; $i >= $min; $i--) {
|
||||
$this->assertEquals($i, $generator->generateInt($min, $max));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This generator generates two bytes at a time, and uses each 8 bit segment of
|
||||
* the generated byte as a coordinate on a grid (so 01011010 would be the
|
||||
* coordinate (0101, 1010) or (5, 10). These are used as inputs to a MonteCarlo
|
||||
* algorithm for the integral of y=x over a 15x15 grid. The expected answer is
|
||||
* 1/2 * 15 * 15 (or 1/2 * base * height, since the result is a triangle).
|
||||
* Therefore, if we get an answer close to that, we know the generator is good.
|
||||
*
|
||||
* Now, since the area under the line should be equal to the area above the line.
|
||||
* Therefore, the ratio of the two areas should be equal. This way, we can avoid
|
||||
* computing total to figure out the areas.
|
||||
*
|
||||
* I have set the bounds on the test to be 80% and 120%. Meaning that I will
|
||||
* consider the test valid and unbiased if the number of random elements that
|
||||
* fall under (inside) of the line and the number that fall outside of the line
|
||||
* are at most 20% apart.
|
||||
*
|
||||
* Since testing randomness is not reliable or repeatable, I will only fail the
|
||||
* test in two different scenarios. The first is if after the iterations the
|
||||
* outside or the inside is 0. The chances of that happening are so low that
|
||||
* if it happens, it's relatively safe to assume that something bad happened. The
|
||||
* second scenario happens when the ratio is outside of the 20% tolerance. If
|
||||
* that happens, I will re-run the entire test. If that test is outside of the 20%
|
||||
* tolerance, then the test will fail
|
||||
*
|
||||
*
|
||||
* @dataProvider provideGenerators
|
||||
*/
|
||||
public function testGenerate(\RandomLib\Generator $generator, $times)
|
||||
{
|
||||
$ratio = $this->doTestGenerate($generator, $times);
|
||||
if ($ratio < 0.8 || $ratio > 1.2) {
|
||||
$ratio2 = $this->doTestGenerate($generator, $times);
|
||||
if ($ratio2 > 1.2 || $ratio2 < 0.8) {
|
||||
$this->fail(
|
||||
sprintf(
|
||||
'The test failed multiple runs with final ratios %f and %f',
|
||||
$ratio,
|
||||
$ratio2
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function doTestGenerate(\RandomLib\Generator $generator, $times)
|
||||
{
|
||||
$inside = 0;
|
||||
$outside = 0;
|
||||
$on = 0;
|
||||
for ($i = 0; $i < $times; $i++) {
|
||||
$byte = $generator->generate(2);
|
||||
$byte = unpack('n', $byte);
|
||||
$byte = array_shift($byte);
|
||||
$xCoord = ($byte >> 8);
|
||||
$yCoord = ($byte & 0xFF);
|
||||
if ($xCoord < $yCoord) {
|
||||
$outside++;
|
||||
} elseif ($xCoord == $yCoord) {
|
||||
$on++;
|
||||
} else {
|
||||
$inside++;
|
||||
}
|
||||
}
|
||||
$this->assertGreaterThan(0, $outside, 'Outside Is 0');
|
||||
$this->assertGreaterThan(0, $inside, 'Inside Is 0');
|
||||
$ratio = $inside / $outside;
|
||||
|
||||
return $ratio;
|
||||
}
|
||||
|
||||
public function getGenerator($random)
|
||||
{
|
||||
$source1 = new Source(array(
|
||||
'generate' => function ($size) use (&$random) {
|
||||
$ret = pack('N', $random);
|
||||
$random--;
|
||||
|
||||
return substr($ret, -1 * $size);
|
||||
},
|
||||
));
|
||||
$sources = array($source1);
|
||||
$mixer = new Mixer(array(
|
||||
'mix'=> function (array $sources) {
|
||||
if (empty($sources)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return array_pop($sources);
|
||||
},
|
||||
));
|
||||
|
||||
return new Generator($sources, $mixer);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user