Bug #12530 Updated: Shuffle shouldn't use the least significant bit of rand()

From: Date: Wed, 03 Jul 2002 23:07:54 +0000
Subject: Bug #12530 Updated: Shuffle shouldn't use the least significant bit of rand()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-13045@lists.php.net to get a copy of this message
ID: 12530 Updated by: eru@php.net Reported By: sulka@sulake.com -Status: Open +Status: Closed Bug Type: Arrays related Operating System: Solaris (most unices) PHP Version: 4.0.6 New Comment: This bug has been fixed in CVS. You can grab a snapshot of the CVS version at http://snaps.php.net/. In case this was a documentation problem, the fix will show up soon at http://www.php.net/manual/. In case this was a PHP.net website problem, the change will show up on the PHP.net site and on the mirror sites. Thank you for the report, and for helping us make PHP better. Previous Comments: ------------------------------------------------------------------------ [2002-04-27 15:53:53] jimw@php.net this is a bug, not a feature request. ------------------------------------------------------------------------ [2001-08-04 18:12:31] andy@php.net reclassified ------------------------------------------------------------------------ [2001-08-02 07:24:41] sulka@sulake.com In ext/standard/array.c, the sorting algorithm of shuffle is defined as (php_rand() % 2) ? 1 : -1 This is fine for rand algorithms in which all bits are random but with Solaris and other unices this is not so. Quoting man random(): "The difference is that rand(3C) produces a much less random sequence-in fact, the low dozen bits generated by rand go through a cyclic pattern. All the bits generated by random() are usable." This is not true however - the LSB of random() calls are predictable on some systems. You can verify if your system is affected by running this: <?PHP $a = array(); $b = array(); for($i=0; $i<1000; $i++) // iterate 1000 times { $foo = ""; // initialize random seq with new seed srand ($i); // create a string with the LSB of first 24 random numbers for($j=0; $j<24; $j++) { $c = rand(); // $c = rand(0,32000); works on all systems // store the random number so we can check how many different // numbers were really generated $b[$c]= 1; // append the least signicant bit to the string $foo .= ($c % 2); } // store the parity string $a[$foo]= 1; } echo "Parity string count: " . count($a), "<BR>"; echo "Random number count: " . count($b), "<BR>"; ?> If the counts are 1000/24000 you're fine. Affected systems I've tried this on return 4/24000. Proposed fix: change shuffle to call PHP's own rand function with limits, ie, rand(0,32000). This introduces randomness into the LSB and fixes shuffle. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=12530&edit=1

« previous php.bugs (#13045) next »