Skip to content

Commit

Permalink
Fix bug with very large ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
ircmaxell committed Jan 18, 2012
1 parent 13c6046 commit e7265ff
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
13 changes: 9 additions & 4 deletions lib/CryptLib/Random/Generator.php
Expand Up @@ -94,14 +94,19 @@ public function generateInt($min = 0, $max = PHP_INT_MAX) {
$range = $max - $min;
if ($range == 0) {
return $max;
} elseif ($range > PHP_INT_MAX) {
// This works, because PHP will auto-convert it to a float at this point
} elseif ($range > PHP_INT_MAX || is_float($range)) {
/**
* This works, because PHP will auto-convert it to a float at this point,
* But on 64 bit systems, the float won't have enough precision to
* actually store the difference, so we need to check if it's a float
* and hence auto-converted...
*/
throw new \RangeException(
'The supplied range is too great to generate'
);
}
$bits = ceil(log($range, 2));
$bytes = max(ceil($bits / 8), 1);
$bits = (int) ceil(log($range, 2));
$bytes = (int) max(ceil($bits / 8), 1);
$mask = (int) (pow(2, $bits) - 1);
/**
* The mask is a better way of dropping unused bits. Basically what it does
Expand Down
14 changes: 14 additions & 0 deletions test/Unit/Random/GeneratorTest.php
Expand Up @@ -167,6 +167,20 @@ public function testGenerateIntFail() {
$n = $this->generator->generateInt(-1, PHP_INT_MAX);
}

/**
* @covers CryptLib\Random\Generator::generateInt
*/
public function testGenerateIntLargeTest() {
$bits = 30;
$expected = 50529027;
if (PHP_INT_MAX > 4000000000) {
$bits = 56;
$expected = 1693273676973062;
}
$n = $this->generator->generateInt(0, pow(2, $bits));
$this->assertEquals($expected, $n);
}

/**
* @covers CryptLib\Random\Generator::generateString
* @dataProvider provideGenerateStringTest
Expand Down

0 comments on commit e7265ff

Please sign in to comment.