Re: Random number generation and phpBB search IDs

From: Date: Sat, 27 Nov 2004 16:55:38 +0000
Subject: Re: Random number generation and phpBB search IDs
References: 1 2  Groups: php.general 
Request: Send a blank email to php-general+get-202959@lists.php.net to get a copy of this message
Gordon McKeown wrote:
Apologies, my mail client was supposed to line-wrap that for me.... ----- Hi, I'm currently experiencing a problem with a phpBB board that appears to be due to the way random number generation works in PHP. I have posted on serveral phpBB boards and have received no answers, so I think I need to understand how PHP is dealing with this in order to resolve it. phpBB generates a unique index for search results using the following code (in search.php): ----- 8< ----- Code ----- 8< ----- mt_srand ((double) microtime() * 1000000); $search_id = mt_rand(); ----- 8< ----- Code ----- 8< ----- The problem is that the seed is generated from the system clock, and if two people search at the exact same moment (or more strictly, if the mt_srand statements get executed at the exact same moment), the random number generation system is initialised with the same seed in each case, so both searches receive the same $search_id, resulting in a MySQL error due to non-unique index fields. Looking through the documentation for PHP, it seems that versions > 4.2.0 do not require the use of mt_srand as they will seed themselves when required. I've had a look at the PHP source code, and from my limited understanding, the seed appears to be generated using a function in php_rand.h: ----- 8< ----- Code ----- 8< ----- #define GENERATE_SEED() ((long)(time(0) * getpid() * 1000000 \ * php_combined_lcg(TSRMLS_C))) ----- 8< ----- Code ----- 8< ----- no need to look as far inside as that... :)
So this is still based to some extent on the current system clock, and the php_combined_lcg function in lcg.c also appears to rely on the current system clock along with the current process/thread ID. There is also some code to ensure that seeding only occurs once. But is this once per thread? Once per process? Once per something-else? per process
What I'm trying to find out is whether this new seeding system will produce the same 'random' number if two mt_rand() statements are executing concurrently. My guess is that they won't, but I don't understand the internals of PHP or Apache well enough to know if their use of threads and processes will ensure uniqueness. Comment out the seeding if you're using PHP 4.2.0+ and it'll work fine. (mt_srand function, not the mt_rand one!)
The problem is occuring with PHP 4.3.9 running under Apache 1.3.33 on Linux kernel 2.4.26 (on a fairly typical cPanel-based shared hosting box). Unfortunately due to the timing-based nature of the problem, it has proven very difficult to set up test cases. I'd be very grateful for any assistance. Gordon.


« previous php.general (#202959) next »