note 76344 deleted from function.srand by nlopess
| From: | nlopess@php.net | Date: | Fri, 13 Jul 2007 19:26:07 +0000 |
| Subject: | note 76344 deleted from function.srand by nlopess | ||
| References: | 1 | Groups: | php.notes php.notes |
| Request: | Send a blank email to php-notes+get-128496@lists.php.net to get a copy of this message | ||
Note Submitter: php at capuzza dot net
----
Richard's statement, that calling srand more than once per script will impair your chance to
get a true random number, is not necessarily correct. In fact using srand more than once can even
improve randomness if you understand how.
The rand function uses a certain algorithm to calculate a number out of the seed given to srand.
This algorithm, of course, is always the same, so without knowing the seed (which is assumed to be
random) you can calculate any value returned by rand other than the first one if you know the first
one. The chances to do so get better the higher the range of your random number is (and are pretty
good if the range of the random number exceeds the possible range of the seed).
In the following example the range of the desired random number is 10 times higher than the possible
range of the seed:
<?
list($usec, $sec) = explode(" ", microtime());
srand((int)($usec*10));
$rand_value = rand(0, 99);
echo($rand_value."<br>");
$rand_value = rand(0, 99);
echo($rand_value."<br>");
$rand_value = rand(0, 99);
echo($rand_value."<br>");
?>
The code will return 3 numbers. Execute the code several times and write down each set of numbers,
you will notice that after a short time you will know the second and the third number by only seeing
the first one and compare it to what you've written down. All that without knowing the random
seed! Of course seeding with (double)microtime()*1000000 gives a 100,000 times higher range, but if
the range of the random numbers you want to generate was 100,000 times higher too, it's just a
matter of time for someone being able to predict all your random numbers after the first one.
But simply calling srand in between the rands wouldn't do the trick either, because the
execution time of the code in between the srands is highly predictable. The key is to do something
before each call of srand, which has a real random time of execution. Requesting a website from
another server would be such a thing (can also be a SQL request or something).
<?
list($usec, $sec) = explode(" ", microtime());
srand((int)($usec*10));
$rand_value = rand(0, 99);
echo($rand_value."<br>");
$foo=file_get_contents
("http://www.google.com/search?q=sea
rch+term+does+not+matter&hl=en");
list($usec, $sec) = explode(" ", microtime());
srand((int)($usec*10));
$rand_value = rand(0, 99);
echo($rand_value."<br>");
$foo=file_get_contents
("http://www.google.com/search?q=sea
rch+term+still+does+not+matter&hl=en");
list($usec, $sec) = explode(" ", microtime());
srand((int)($usec*10));
$rand_value = rand(0, 99);
echo($rand_value."<br>");
?>
You can probably execute this code a thousand times with hardly getting any set of 3 numbers
repeated. Try what you did with the other code snippet above and note that you improved randomness
by using srand more than once.
Via http://www.capuzza.com/detail.php?ID=115293