RE: Random number generation and phpBB search IDs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use a database query to verify the random number has not been used before.

$number_checker = 1;

while ($number_checker != 0){

	#insert your $random_number code

	$query = "SELECT COUNT(*) AS total FROM some_table WHERE
random_number_field = '$random_number'";
	$result = mysql_query($query);
	$number_checker = mysql_result($result, 0, "total");

}

If this is in fact a bug (not likely) and it gets past this too, then wow
start using auto increment or something?

Best,

Thomas S. Crum

-----Original Message-----
From: Gordon Mckeown [mailto:ml_php@xxxxxxxxxxxxxxxx] 
Sent: Saturday, November 27, 2004 11:44 AM
To: php-general@xxxxxxxxxxxxx
Subject:  Random number generation and phpBB search IDs

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< -----

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?

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.

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.

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux