Page 1 of 2

random value (used in phpBB)

Posted: Sun Jan 21, 2007 2:52 pm
by WaldoMonster
I was looking how phpBB did create random values.
And found this code:

Code: Select all

/**
* Our own generator of random values
* This uses a constantly changing value as the base for generating the values
* The board wide setting is updated once per page if this code is called
* With thanks to Anthrax101 for the inspiration on this one
* Added in phpBB 2.0.20
*/
function dss_rand()
{
	global $db, $board_config, $dss_seeded;

	$val = $board_config['rand_seed'] . microtime();
	$val = md5($val);
	$board_config['rand_seed'] = md5($board_config['rand_seed'] . $val . 'a');
   
	if($dss_seeded !== true)
	{
		$sql = "UPDATE " . CONFIG_TABLE . " SET
			config_value = '" . $board_config['rand_seed'] . "'
			WHERE config_name = 'rand_seed'";
		
		if( !$db->sql_query($sql) )
		{
			message_die(GENERAL_ERROR, "Unable to reseed PRNG", "", __LINE__, __FILE__, $sql);
		}

		$dss_seeded = true;
	}

	return substr($val, 4, 16);
}

I have looked around for dss and random on the internet, but only found phpBB related articles.
Is there a common name for this algorithm?
Is there any website explaining this algorithm?
Or is it a unique phpBB code?

Posted: Sun Jan 21, 2007 3:04 pm
by feyd
Hashing a previous hash, even padded, is often not recommended. The math doesn't work out well. The reason why is entropy. Hash results have pretty low entropy. Coupled with uniform result length, makes it that much easier.

Honestly, I have to say that is wishful at best.

Posted: Sun Jan 21, 2007 4:33 pm
by Ollie Saunders
what's wrong with mt_rand() for generating random values?

Posted: Sun Jan 21, 2007 5:07 pm
by WaldoMonster
ole wrote:what's wrong with mt_rand() for generating random values?
What I read from the Internet that there is no real random generator for PHP.
Many articles conclude that mt_rand() is better than rand().
I found this an interesting article:
http://portfolio.technoized.com/notes/26

Posted: Sun Jan 21, 2007 5:18 pm
by feyd
Mersenne Twist sequences have far longer runs before repeating than those used by rand(). This is their benefit, however they will repeat eventually.

Truly random data isn't readily available in most operating environments unfortunately. /dev/urandom is a good source for high entropy on many Linux systems. There are services available online that provide truly random streams when random number generation is required.

Posted: Sun Jan 21, 2007 11:15 pm
by AKA Panama Jack
I use this...

Code: Select all

mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff);

$random_number = mt_rand(1, $whatever);
Using the algorithm above to reset the seed for mt_rand seems to work perfectly as I haven't had any sequence ever repeat.

Posted: Mon Jan 22, 2007 8:59 am
by Mordred
You don't need to seed the mt_rand, it's autoseeded for you on script start, and I suspect that it's better than your seeding with all those fishy md5/substr calls. Every time you hash something its entropy diminishes, so why do it at all?

Posted: Mon Jan 22, 2007 9:38 am
by Maugrim_The_Reaper
Older PHP versions require mt_srand() for seeding. Has not been required for a long time though, so BC is the only reason for this. Hashing should be avoided for seeds - see feyd's earlier comments. For most uses mt_rand() should suffice without much interference, the period is large enough for the majority for applications.

phpBB's code is...odd. Not sure what all that jumping through hoops is going to accomplish except a lot of head scratching...;).

Posted: Mon Jan 22, 2007 9:59 am
by Ollie Saunders
phpBB's code is...[s]odd[/s] poop

fixed

Posted: Mon Jan 22, 2007 11:36 am
by AKA Panama Jack
Mordred wrote:You don't need to seed the mt_rand, it's autoseeded for you on script start, and I suspect that it's better than your seeding with all those fishy md5/substr calls. Every time you hash something its entropy diminishes, so why do it at all?
True it is automatically seeded on PHP 4.2.0 and higher but if your program is still compatible with versions of PHP older than 4.2 it is best to reseed the random number generators your self. And as I mentioned from my testing the reseeding method I mentioned hasn't given any duplicate random number sequences so it seems to do it's job quite well. :)

Posted: Mon Jan 22, 2007 11:41 am
by Ollie Saunders
Have you tried those same tests with just calling mt_rand()?

Posted: Tue Jan 23, 2007 9:29 am
by WaldoMonster
Thanks all for the feedback.
I still have a related question.
Is there a difference in randomness between?

Code: Select all

// Contacting 40x (1 digit base36)
mt_rand(0,36-1)

// Contacting 8x (36^5-1 = 5 digits base36)
mt_rand(0, 60466176-1);

Posted: Tue Jan 23, 2007 9:41 am
by feyd
There's a difference in the range, so yes.

mt_getrandmax() should also be used to make sure you don't set a value too high.

Posted: Tue Jan 23, 2007 10:10 am
by WaldoMonster
feyd wrote:There's a difference in the range, so yes.

mt_getrandmax() should also be used to make sure you don't set a value too high.
Is it better to concat less large mt_rand() within the mt_getrandmax() range
or concat more small mt_rand() with the same total length?
(see example above)

Posted: Tue Jan 23, 2007 10:21 am
by feyd
What I typically will do is use mt_rand() with mt_getrandmax() to build a decimal value. I then multiply the decimal value by the end scale to reach the actual value. It will have rounding errors for very large ranges, but that's fairly unless you have access to even better random streams.