芝麻web文件管理V1.00
编辑当前文件:/home/mgatv524/apv.mgaplay.com.br/vendor/ircmaxell/random-lib/test/Vectors/Random/GeneratorTest.php
* @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); } }