How unique is uniqid?

Php

Php Problem Overview


This question isn't really a problem looking for a solution, it's more just a matter of simple curiosity. The PHP uniqid function has a more entropy flag, to make the output "more unique". This got me wondering, just how likely is it for this function to produce the same result more than once when more_entropy is true, versus when it isn't. In other words, how unique is uniqid when more_entropy is enabled, versus when it is disabled? Are there any drawbacks to having more_entropy enabled all the time?

Php Solutions


Solution 1 - Php

Update, March 2014:

Firstly, it is important to note that uniqid is a bit of a misnomer as it doesnt guarantee a unique ID.

Per the PHP documentation:

> WARNING! > > This function does not create random nor unpredictable string. This > function must not be used for security purposes. Use cryptographically > secure random function/generator and cryptographically secure hash > functions to create unpredictable secure ID.

And

> This function does not generate cryptographically secure tokens, in > fact without being passed any additional parameters the return value > is little different from microtime(). If you need to generate > cryptographically secure tokens use openssl_random_pseudo_bytes().


Setting more-entropy to true generates a more unique value, however the execution time is longer (though to a tiny degree), according to the docs:

> If set to TRUE, uniqid() will add additional entropy (using the > combined linear congruential generator) at the end of the return > value, which increases the likelihood that the result will be unique.

Note the line increases the likelihood that the result will be unique and not that is will guarantee uniqueness.

You can 'endlessly' strive for uniqueness, up to a point, and enhance using any number of encryption routines, adding salts and the like- it depends on the purpose.

I'd recommend looking at the comments on the main PHP topic, notably:

http://www.php.net/manual/en/function.uniqid.php#96898

http://www.php.net/manual/en/function.uniqid.php#96549

http://www.php.net/manual/en/function.uniqid.php#95001

What I'd recommend is working out why you need uniqueness, is it for security (i.e. to add to an encryption/scrambling routine)? Also, How unique does it need to be? Finally, look at the speed consideration. Suitability will change with the underlying considerations.

Solution 2 - Php

Things are only unique if you check that they don't exist already. It doesn't matter what function you use to generate a 'random' string, or ID - if you don't double check that it isn't a duplicate, then there's always that chance.. ;)

While uniqid is based on the current time, the cautionary note above still applies - it just depends on where you will be using these "unique IDs". The clue to all this is where it says "more unique". Unique is unique is unique. How you can have something which is more or less unique, is a bit confusing to me!

Checking as above, and combining all this stuff will let you end up with something approaching uniqueness, but its all relative to where the keys will be used and the context. Hope that helps!

Solution 3 - Php

From the discussions about the function on the PHP manual site:

> As others below note, without prefix > and without "added entropy", this > function simply returns the UNIX > timestamp with added microsecond > counter as a hex number; it's more or > less just microtime(), in hexit form. > > [...] > > Also worth to note is that since microtime() only works on systems that have gettimeofday() > present, which Windows natively DOES NOT, uniqid() might yield just the single-second-resolution UNIX timestamp in a Windows environment.

In other words without "more_entropy", the function is absolutely horrible and should never be used, period. Accoding to the documentation, the flag will use a "combined linear congruential generator" to "add entropy". Well, that's a pretty weak RNG. So I'd skip this function entirely and use something based on mt_rand with a good seed for things that are not security-relevant, and SHA-256 for things that are.

Solution 4 - Php

Without the more_unique flag, it returns the unix timestamp with a microsecond counter, therefore if two calls get made at the same microsecond then they will return the same 'unique' id.

From there it is a question of how likely that is. The answer is, not very, but not to a discountable degree. If you need a unique id and you generate them often (or work with data generated elsewhere), don't count on it to be absolutely unique.

Solution 5 - Php

The relevant bit from the source code is

if (more_entropy) {
	uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10);
} else {
	uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec);
}

So more_entropy adds nine somewhat random decimal digits (php_combined_lcg() returns a value in (0,1)) - that's 29.9 bits of entropy, tops (in reality probably less as LCG is not a cryptographically secure pseudorandom number generator).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGordonMView Question on Stackoverflow
Solution 1 - PhpSW4View Answer on Stackoverflow
Solution 2 - PhpdmpView Answer on Stackoverflow
Solution 3 - PhpMichael BorgwardtView Answer on Stackoverflow
Solution 4 - PhpReese MooreView Answer on Stackoverflow
Solution 5 - PhpTgrView Answer on Stackoverflow