Edit report at https://bugs.php.net/bug.php?id=55519&edit=1
ID: 55519 Updated by: ahar...@php.net Reported by: sergio dot bobillier at gmail dot com Summary: mt_rand only generetes even 64 bits numbers Status: Assigned Type: Bug Package: Math related Operating System: Linux (Ubuntu 11.04 x64) PHP Version: Irrelevant Assigned To: aharvey Block user comment: N Private report: N New Comment: OK, so this behaves normally for bounds up to 2^32, then does weird things after that. Given this script: <?php $iterations = 1000; function mt_check($lower, $upper) { global $iterations; $stats = array_reduce(array_map(function ($v) use ($lower, $upper) { return mt_rand($lower, $upper); }, range(1, $iterations)), function ($acc, $v) { $v % 2 ? $acc['odd']++ : $acc['even']++; return $acc; }, array('odd' => 0, 'even' => 0)); echo "Stats for $iterations iterations of $lower..$upper: $stats[odd] odd; $stats[even] even\n"; } foreach (range(2, 62) as $pow) { mt_check(pow(2, $pow - 1), pow(2, $pow)); } ?> The results are this: Stats for 1000 iterations of 2..4: 319 odd; 681 even Stats for 1000 iterations of 4..8: 414 odd; 586 even Stats for 1000 iterations of 8..16: 452 odd; 548 even Stats for 1000 iterations of 16..32: 443 odd; 557 even Stats for 1000 iterations of 32..64: 475 odd; 525 even Stats for 1000 iterations of 64..128: 492 odd; 508 even Stats for 1000 iterations of 128..256: 486 odd; 514 even Stats for 1000 iterations of 256..512: 482 odd; 518 even Stats for 1000 iterations of 512..1024: 505 odd; 495 even Stats for 1000 iterations of 1024..2048: 502 odd; 498 even Stats for 1000 iterations of 2048..4096: 480 odd; 520 even Stats for 1000 iterations of 4096..8192: 485 odd; 515 even Stats for 1000 iterations of 8192..16384: 501 odd; 499 even Stats for 1000 iterations of 16384..32768: 513 odd; 487 even Stats for 1000 iterations of 32768..65536: 508 odd; 492 even Stats for 1000 iterations of 65536..131072: 498 odd; 502 even Stats for 1000 iterations of 131072..262144: 510 odd; 490 even Stats for 1000 iterations of 262144..524288: 514 odd; 486 even Stats for 1000 iterations of 524288..1048576: 498 odd; 502 even Stats for 1000 iterations of 1048576..2097152: 496 odd; 504 even Stats for 1000 iterations of 2097152..4194304: 488 odd; 512 even Stats for 1000 iterations of 4194304..8388608: 497 odd; 503 even Stats for 1000 iterations of 8388608..16777216: 493 odd; 507 even Stats for 1000 iterations of 16777216..33554432: 498 odd; 502 even Stats for 1000 iterations of 33554432..67108864: 458 odd; 542 even Stats for 1000 iterations of 67108864..134217728: 500 odd; 500 even Stats for 1000 iterations of 134217728..268435456: 499 odd; 501 even Stats for 1000 iterations of 268435456..536870912: 480 odd; 520 even Stats for 1000 iterations of 536870912..1073741824: 512 odd; 488 even Stats for 1000 iterations of 1073741824..2147483648: 487 odd; 513 even Stats for 1000 iterations of 2147483648..4294967296: 492 odd; 508 even Stats for 1000 iterations of 4294967296..8589934592: 0 odd; 1000 even Stats for 1000 iterations of 8589934592..17179869184: 0 odd; 1000 even Stats for 1000 iterations of 17179869184..34359738368: 0 odd; 1000 even Stats for 1000 iterations of 34359738368..68719476736: 0 odd; 1000 even Stats for 1000 iterations of 68719476736..137438953472: 0 odd; 1000 even Stats for 1000 iterations of 137438953472..274877906944: 0 odd; 1000 even Stats for 1000 iterations of 274877906944..549755813888: 0 odd; 1000 even Stats for 1000 iterations of 549755813888..1099511627776: 0 odd; 1000 even Stats for 1000 iterations of 1099511627776..2199023255552: 0 odd; 1000 even Stats for 1000 iterations of 2199023255552..4398046511104: 0 odd; 1000 even Stats for 1000 iterations of 4398046511104..8796093022208: 0 odd; 1000 even Stats for 1000 iterations of 8796093022208..17592186044416: 0 odd; 1000 even Stats for 1000 iterations of 17592186044416..35184372088832: 0 odd; 1000 even Stats for 1000 iterations of 35184372088832..70368744177664: 4 odd; 996 even Stats for 1000 iterations of 70368744177664..140737488355328: 4 odd; 996 even Stats for 1000 iterations of 140737488355328..281474976710656: 5 odd; 995 even Stats for 1000 iterations of 281474976710656..562949953421312: 20 odd; 980 even Stats for 1000 iterations of 562949953421312..1125899906842624: 34 odd; 966 even Stats for 1000 iterations of 1125899906842624..2251799813685248: 66 odd; 934 even Stats for 1000 iterations of 2251799813685248..4503599627370496: 141 odd; 859 even Stats for 1000 iterations of 4503599627370496..9007199254740992: 272 odd; 728 even Stats for 1000 iterations of 9007199254740992..18014398509481984: 0 odd; 1000 even Stats for 1000 iterations of 18014398509481984..36028797018963968: 0 odd; 1000 even Stats for 1000 iterations of 36028797018963968..72057594037927936: 0 odd; 1000 even Stats for 1000 iterations of 72057594037927936..144115188075855872: 0 odd; 1000 even Stats for 1000 iterations of 144115188075855872..288230376151711744: 0 odd; 1000 even Stats for 1000 iterations of 288230376151711744..576460752303423488: 0 odd; 1000 even Stats for 1000 iterations of 576460752303423488..1152921504606846976: 0 odd; 1000 even Stats for 1000 iterations of 1152921504606846976..2305843009213693952: 0 odd; 1000 even Stats for 1000 iterations of 2305843009213693952..4611686018427387904: 0 odd; 1000 even As any good engineer who's baffled would say: hmmm, that's interesting. Previous Comments: ------------------------------------------------------------------------ [2011-08-28 03:40:06] ahar...@php.net Verified on 64-bit OS X, at least beyond a certain set of mt_rand() bounds. Not entirely sure what those actual bounds are yet. ------------------------------------------------------------------------ [2011-08-27 09:09:30] sergio dot bobillier at gmail dot com Description: ------------ I was doing a lame RSA implementation when I discovered that mt_rand only generates even numbers when the number is a 64 bits integer. The Test script shows the script I used to generate two 64 bits integers p and q with mt_rand. I was doing primality test only with odd numbers since even numbers are not prime but the script never do the primality test because all the generated numbers are even. I thought this might be an integer overflow problem but I'm doing this on a 64 bits system and the var_dump function shows that the variables are actually integers like so: int(2117698586505379840) int(1690740540401778688) int(3279295862706012160) int(4526730875131396096) int(3188107862534520832) int(1914802535743356928) int(4172596828035874816) int(4559249790717657088) int(1938449129751445504) int(1859647742213619712) Test script: --------------- function is_prime($num) { // See if the number is prime echo "Primality test"; return true; } function gen_keys() { // 1. find two 64 bits primes p and q $p = 0; $q = 0; while(!$p) { $p = mt_rand(72057594037927936, 4611686018427387904); // debugging: var_dump($p); if($p % 2 == 0) { $p = 0; } else { // Primality test in another function // (not important here) echo "odd"; if(!is_prime($p)) $p = 0; } } echo $p; } Expected result: ---------------- I expect the mt_rand to generate some odd numbers and make the script go through the primality test or at least print "odd" Actual result: -------------- The script doesn't reach the primality or print "odd" test because all generated numbers are even. ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=55519&edit=1