Bug #12455 Updated: Srand and shuffle give odd results

From: Date: Tue, 31 Jul 2001 16:09:39 +0000
Subject: Bug #12455 Updated: Srand and shuffle give odd results
References: 1  Groups: php.dev 
Request: Send a blank email to php-dev+get-61664@lists.php.net to get a copy of this message
ID: 12455 Updated by: jflemer Reported By: sulka@sulake.com Old Status: Bogus Status: Open Bug Type: *Math Functions Operating System: All PHP Version: 4.0.4pl1, 4.0.6 New Comment: OK, well can you check to see that microtime() is working for you? This script should print out 100. <?php $a = array(); for($i=0; $i<100; $i++) { $a[((double)microtime()*1000000)]= 1; } echo count($a), "\n"; ?> BTW, your most recent example (calling a "remote" script) is essentially the same as calling the local function pwd(). You still are re-seeding the PRNG with each time you call the function. In order to produce a pseudo-random sequence you should only seed the PRNG once. This is a hard thing to do in the case where you generate one random number from the sequence per execution. Here is something that works for me even though I call the srand() function inside the function (though the randomness is probably pretty poor). You might be able to adapt it in some way for your use. The idea here is that once you shuffle the array once, you use that as the starting point for the next shuffle. <?php $pass_array = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',0,1,2,4,5,6,7,8,9); function pwd(&$pass_array) { srand ((double)microtime()*1000000); $password = ''; shuffle(&$pass_array); for ($i=0; $i<6; $i++) { $password .= $pass_array[$i]; } return $password; } $a = array(); for($i=0; $i<500; $i++) { $a[pwd($pass_array)] = 1; } echo count($a), "\n"; This is not a *bug* (IMHO). This is a problem with your script, you might want to try this discussion on php-general@lists.php.net and see if people have more suggestions for you. Previous Comments: ------------------------------------------------------------------------ [2001-07-31 10:20:27] sulka@sulake.com Ok, here's sample code that should wake you up. The problem occurs even when srand is only called once / page load. Create two PHP pages: password.php <?PHP $password = ""; $array = array('a','b','c','d','e','f','g','h','i','j','k','l','m',' n','o','p','q','r','s','t','u','v','w','x','y','z',0,1,2,4, 5,6,7,8,9); srand ((double)microtime()*1000000); shuffle(&$array); for ($i=0; $i<6; $i++) { $password .= $array[$i]; } echo $password;?> load100times.php <?PHP $i=0; while($i<100) { $file = fopen ("http://localhost/password.php", "r"); $password = fgets ($file, 128); fclose($file); $a[$password] = $password; $i++; } echo "Count: " . count($a); ?> Then load the load100times.php in your browser. The result should be 100 but is still 4 on the machines I'm testing on. I'm assuming srand is not ment to be run only once / server start? ------------------------------------------------------------------------ [2001-07-31 10:00:28] jflemer@php.net Try moving your srand() call outside of the pwd() function. That should fix it. The posted script returns 4 for me on Solaris 5.8, and 500 when I move the srand() outside of pwd(). srand() should only be called *once*. Reopen this if that does not fix it. ------------------------------------------------------------------------ [2001-07-30 06:25:27] sulka@sulake.com The same problem also occurs on PHP 4.0.6 on Darwin/PPC. System info: PHP Version 4.0.6 System: Darwin localhost 1.3.7 Darwin Kernel Version 1.3.7: Sat Jun  9 11:12:48 PDT 2001; root:xnu/xnu-124.13.obj~1/RELEASE_PPC  Power Macintosh powerpc Configure Command './configure' '--with-mysql=/usr/local' '--with-apxs=/usr/sbin/apxs' '--with-zlib=/usr' Server API: Apache Apache Version: Apache/1.3.20 ------------------------------------------------------------------------ [2001-07-30 05:17:09] sulka@sulake.com A friend tried to run the test code on his machine and also got 4 as a result. This is a Linux machine so my original guess of this being Solaris specific isn't true. The only real common denominator seems to be the PHP version? I'm trying to get an upgrade to see if this is happening under 4.0.6. Here's more info on the two servers this is occuring on: PHP Version: 4.0.4pl1 System: Linux xxx.com 2.2.14 #2 SMP Tue Mar 14 14:42:34 PST 2000 i686 unknown Configure Command: './configure' '--with-apxs=/usr/local/apache/bin/apxs' '--with-xml' '--with-mcrypt' '--with-mysql' '--enable-track-vars' Server API: Apache System: SunOS yyy.com 5.8 Generic_108528-02 sun4u sparc SUNW,UltraSPARC-IIi-cEngine Configure Command: './configure' '--with-apache=../apache_1.3.14' '--with-mysql=/usr/local/mysql' '--with-ldap=/usr/local' '--with-db3=/usr/local/BerkeleyDB.3.2' '--with-gd=../gd1.5' '--with-ttf=/usr/local' '--enable-wddx' ------------------------------------------------------------------------ [2001-07-29 16:41:51] sulka@sulake.com Well, when I run that code I get 4, not 500. Upping the number of iterations doesn't help. I think the problem is with the particular build (extension/OS combination). Any way to debug this? ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/?id=12455 Edit this bug report at http://bugs.php.net/?id=12455&edit=1

« previous php.dev (#61664) next »