RFC: rand() change, second try
| From: | Jeroen van Wolffelaar | Date: | Thu, 16 Aug 2001 19:04:30 +0000 |
| Subject: | RFC: rand() change, second try | ||
| Groups: | php.dev | ||
| Request: | Send a blank email to php-dev+get-63464@lists.php.net to get a copy of this message | ||
Hi,
[Impact and relevance: all functions that use randomness (including
array_shuffle&co)]
After the previous discussion, I've been thinking, and I think I've got a
way which has only a neglectible BC problem (unlike my first proposal),
while still keeping the following in mind:
Probably 99% or more people who use rand() & co, simply want as random
numbers as possible. In _this_ context, you can say that algorithms are
exchangable. Most people don't know/don't want to know about seeding
pseudo-random-generators, which algorithms to use, and that kind of stuff,
they simply want random numbers. For the <1% people that want to exploit the
property that you get the same "random" numbers after feeding the same seed,
_do_ know about that.
This proposal has these advantages:
- Technical and syntactical possibility to add other sources of randomness:
real random numbers (by means of device or internet-source)/other
algorithms. No new functions needed in such cases.
- Very easy to work with random numbers, this allows quick and easy coding
with randomness without needing to worry about how random it is: PHP takes
care of it, tunable by ini-entries.
- Usually no need for srand().
- Still regression tests possible, with more relevant syntax
- Seeding specific numbers and the choice of algorithm also influence
functions like array_shuffle.
- ?
Disadvantages:
- Minor break of BC, only if you AND expect a certain number after a certain
seed AND you use various random-based functions through eachother.
- A very small extra startuptime for each script-execution
- Mixed use of algorithms a bit troublesome (no problem in case of serial
mixed use)
- ?
Below I give some examples in stead of some technical explaination.
Please let me know what you think of it,
Jeroen
--------------------------------------------------
I think I can illustrate my proposal best with some examples:
[note: simplified sometimes, it's about functionality, not implementation]
=========
[ini]
random_generator = algorithm-x ; typical 'mt' (default)
========
// for simply random numbers:
<?php
file://seed the random number generator "algorithm-x" with a 'random' seed
(1e6*microtime())
srand(); // (no parameters)
echo rand(); // use "algorithm-x"
?>
========
// for simply random numbers:
<!- on script start, implicit call to srand() (noargs) ->
<?php
echo rand(); // use "algorithm-x"
?>
These two previous scripts are equivalent with:
algx_srand( (float) microtime() * 1e6);
agx_rand();
========
// for a specific seed:
<?php
// state that you want to use MT with seed 1234 in all next calls to any
random function
srand(1234, RAND_MT );
echo rand(1,6); // throw with a dice, using mt.
shuffle($array); // this also is affected
?>
========
// mixed
<?php
// state that you want to use the system rand() with seed 1234 in all next
calls to any random function
srand(1234, RAND_SYSTEM );
echo rand(1,6); // throw with a dice, using system rand().
shuffle($array); // this also is affected
srand(); // back to default behaviour
echo rand(1,6); // algx, seeded with 1e6*microtime() on previous line
?>
========
// also impact on other random functions
<?php
srand(456, RAND_MT );
array_shuffle($array); // This shuffles the same way each time!
?>
======
If you seed a specific seed, that's possible, but you need to specify the
algorithm. (which can be extended!). This is simply because it wouldn't make
much sense otherwise.
Calling srand() (no-args) while a real-random source is selected, will have
no effect.
[mt_]srand($arg1) with one argument is deprecated.
mt_* are aliasses for their equivelents, so no double set of functions
anymore.
In PHP 5, all this deprecated stuff should be removed.
======
// BC: goes OK
srand(123); // equivalent to: srand(123,RAND_SYSTEM);
echo rand();
======
// BC: goes OK
mt_srand(321); // equivalent to: srand(321,RAND_MT);
echo mt_rand(); // alias of rand()
======
// BC: changed behaviour, but this is extremely unlikely
// You don't mix up mt and system rand...
mt_srand(321); // equivalent to: srand(321,RAND_MT);
echo rand(); // will use MT, seeded with 321
srand(123); // equivalent to: srand(123,RAND_SYSTEM);
echo mt_rand(); // will use SYSTEM, seeded with 123
======
// BC: changed behaviour, but this is extremely unlikely
mt_srand(321); // equivalent to: srand(321,RAND_MT);
array_shuffle($array); // will eat up some random numbers
echo mt_rand(); // not the first in the batch, since they have been eaten up
======