Forum Moderators: coopster

Message Too Old, No Replies

How random is rand() ?

         

webfoo

12:26 am on Jun 28, 2008 (gmt 0)

10+ Year Member



Does anyone know how random the rand() function really is? What are the chances of landing on a number twice?

Can you specify a length parameter? (longer the number, less odds of hitting it twice).

webfoo

StoutFiles

1:04 am on Jun 28, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



About as random as a computer can be.

The length parameter also depends on the language being used...I'm going to assume you mean PHP.

<?php echo rand(2,20); ?>
//gives you a number between 2 and 20

webfoo

9:12 pm on Jul 21, 2008 (gmt 0)

10+ Year Member



Is it random enough to rely on for generating a unique ID?

eelixduppy

9:19 pm on Jul 21, 2008 (gmt 0)



>> Is it random enough to rely on for generating a unique ID?

Yes, it should be.

>> What are the chances of landing on a number twice?

Depends on the range of numbers you are selecting from :)

NomikOS

12:54 am on Jul 22, 2008 (gmt 0)

10+ Year Member



StoutFiles is right.
perhaps you need something like this:
$random = uniqid();

dreamcatcher

7:23 am on Jul 22, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This is what I use:

substr(md5(uniqid(rand(),1)), 3, 10);

dc

PHP_Chimp

8:49 am on Jul 22, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There is a note on the uniqid page about using md5(uniqid(...)), as the md5 is not unique, however as the uniqid is based on the microtime, unless you get 2 requests handled simultaneously then this should always be different.

So if you md5 the result of uniqid then you take something with an incredibly high chance (as nothing is guaranteed) of being unique and hash it with something that is known to have collisions...so you have actually just decreased the chance of a unique number.

From the user comments section of the manual.

<?php
$better_token = uniqid(md5(rand()), true);
?>

Taking a substring of the md5 generated (if you use the technique in the manual) does not increase the chance of a randomly generated number...unless of course you introduce another source of randomness like using rand to determine where that substring starts.
So you could do something like:

substr(md5(uniqid(rand(),1)), rand(0,21), 10);

This does seem to be getting a little more complicated than just uniqid...and there is still the problem that the final 10 character string has been taken--albeit randomly--from a string that is known to be produced from more than one starting point.

If you want to be really random then you could use something like:


function randomizer($length) { // $length = 9 if you want a 32 character string
$str = '';
$prefix = '';
for ($i=0;$i<$length;$i++) {
$prefix.= chr(mt_rand(33,126)); // viable ascii characters, could use 32 if you want to include a space
}
$str.= uniqid($prefix, true);
return $str;
}

Although this looks similar to the md5(uniqid(...)) construct the difference is that as md5 is not random or unique; so we are using as random a method of generating our prefix as a computer will allow--however this is still not guaranteed to be unique, the uniqid provides that part.

By calling substr against the result it would be possible to reduce the length of the 'random' string, however this will reduce the effectiveness of the randomness.
As if you have to pick a single random letter from the ascii alphabet then you have 93 options. If you have to pick a 2 character string then you square the number of options. So the longer the string the harder it will be to guess that string, as there are many more options.

However you probably noticed that the heart of the function is uniqid, so it would be a lot easier just not to bother with a random prefix and allow uniqid to do the work of producing a 13 or 23 character string.
You can then add a prefix if you choose to, maybe for the reason noted in the manual.

As unless you are trying to use this function as part of an encryption algorithm then randomness if not really a problem.
I assume that you are not just using an ID for loggin in. I assume that a password of some description is also required. So if I know an ID I still have to know the password. Uniqid is just a much better option for ID's than an auto increment number, however a 'random' ID is not enough security to verify the identity of a user, you need something else, like a password.