[ACCEPTED]-How unique is uniqid?-php

Accepted answer
Score: 38

Update, March 2014:

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

Per the PHP documentation:


This function does 29 not create random nor unpredictable string. This function 28 must not be used for security purposes. Use 27 cryptographically secure random function/generator 26 and cryptographically secure hash functions 25 to create unpredictable secure ID.


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

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

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

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

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

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




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

Score: 20

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

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

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

Score: 11

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

As others below note, without 19 prefix and without "added entropy", this function 18 simply returns the UNIX timestamp with 17 added microsecond counter as a hex number; it's 16 more or less just microtime(), in hexit 15 form.


Also worth to note is that since 14 microtime() only works on systems that have 13 gettimeofday() > present, which Windows 12 natively DOES NOT, uniqid() might yield 11 just the single-second-resolution UNIX timestamp 10 in a Windows environment.

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

Score: 8

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

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

Score: 5

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 5 random decimal digits (php_combined_lcg() returns a value 4 in (0,1)) - that's 29.9 bits of entropy, tops 3 (in reality probably less as LCG is not 2 a cryptographically secure pseudorandom 1 number generator).

More Related questions