Why does PHPs uniqid function return only 13 digits and not 14?

31,735

Solution 1

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

Makes sense to me. Comment if you need an explanation

For the record, the underlying function to uniqid() appears to be roughly as follows:

$m=microtime(true); sprintf("%8x%05x\n",floor($m),($m-floor($m))*1000000);

In other words, first 8 hex chars = Unixtime, last 5 hex chars = microseconds. This is why it has microsecond precision. Also, it provides a means by which to reverse-engineer the time when a uniqid was generated:

date("r",hexdec(substr(uniqid(),0,8)));

Increasingly as you go further down the string, the number becomes "more unique" over time, with the exception of digit 9, where numeral prevalence is 0..3>4>5..f, because of the difference between 10^6 and 16^5 (this is presumably true for the remaining digits as well but much less noticeable).

Solution 2

I think the number generated by uniqid is based on the current time in microseconds -- but it is not that time : the calculation is probably a bit harder that you think.

Still, if you need more than 13 digits, you can pass true as a second parameter to uniqid, to have more entropy -- and it'll give you a string that's 23 characters longs.


For instance, with this portion of code :

var_dump(uniqid());
var_dump(uniqid('', true));

I just got :

string '4ba284384e4ca' (length=13)
string '4ba284384e4df9.73439132' (length=23)

Solution 3

For a 32 character unique ID try this:

$unique = uniqid(rand(), true);

To shorten it just use substr():

$unique = substr(uniqid(rand(), true), 16, 16); // 16 characters long
Share:
31,735
Marco Demaio
Author by

Marco Demaio

Just love coding all day long! Now I'm using PHP and Javascript for my daytime job. I took part in realizing all the back end application to handle the orders, contracts and invoices for a site that sells posta certificata per aziende. Language I love most is C++ Language I hate most is VB6/VB.NET Wishes: to see PHP becoming more OO with operator overloading, and Python add curly braces. I have started coding in BASIC since I was a 13 years old kid with a Commodore 64 and Apple II. During University they taught me C and C++ and JAVA and I realized even more how much I love to code. :) Funny stuff: Micro Roundcube plugin to improve the search box

Updated on May 15, 2020

Comments

  • Marco Demaio
    Marco Demaio almost 4 years

    uniqid() function returns a 13 digits long hexadecimal number. According to the spec in php.net site, the function uses microtime to generate the unique value.

    But microtime returns numbers in string format as the following one:

    "0.70352700 12689396875"
    

    which are basically the microseconds and the seconds elapsed since 1970. This is a 9+11 digits decimal number.

    Converting a 20 decimal number into hex would result in a 16 digits hexadecimal NOT a 13 digits one.

    I also thought to take out the "0." part that seem to never change, and the last two digits of the microsec part that seem to remain always "00". Doing this the decimal number would be only 9+11-3 digits long, but still a decimal number of 17 digits when converted into hex would result in 14 digits hexadecimal number NOT 13.

    I'M NOT INTERESTED IN GETTING A UNIQUE ID IN ANOTHER WAY OR A LONGER/SHORTER UNIQUE ID! I'M ONLY ASKING IF SOMEONE KNOWS WHY DOES uniqid RETURNS ONLY 13 DIGITS.

    It seems nosense: if uniqid returns one digit less than microtime, it means that microtime gives out results that are more unique of the ones returned by uniqid.

  • Tom
    Tom about 14 years
    Wouldn't that severely impact the chances of duplicates?
  • Marco Demaio
    Marco Demaio about 14 years
    This does not answer to my question, the point remains why the uniqid function returns a value that is only 13 chars long. Since is missing a digit, it can't' be as unique as microtime() function. Anyway thanks for the suggestion.
  • John Conde
    John Conde about 14 years
    The chances would still be extremely small and virtually unlikely to ever happen. However, if the goal was to ensure maximum uniqueness the whole MD5 should be used.
  • Frank Farmer
    Frank Farmer about 14 years
    md5() doesn't introduce any more entropy at all. If anything, it removes a little, since there's a small chance of hash collision.
  • Frank Farmer
    Frank Farmer about 14 years
    You're adding characters, but reducing entropy and uniqueness.
  • salathe
    salathe about 14 years
    A Unix timestamp's seconds can 'fit' within 8 hexadecimal characters up to early Feb 2106 ((hex) FFFFFFFF is (dec) 4294967295). A microsecond is one millionth of a second so the largest microsecond value is 999999 (any larger and it will be the next whole second) or F423F in hexadecimal. So: 13 hexadecimal characters to represent Unix time to the microsecond.
  • Petah
    Petah over 13 years
    md5 is not collision resistant and should not be used as for this
  • Petah
    Petah over 13 years
    md5 is not collision resistant and should not be used as for this
  • Michael D. Irizarry
    Michael D. Irizarry about 12 years
    Sorry my bad, totally forgot to add the complete example md5(uniqid(mt_rand(), true)); uniqid is the one that has more entropy.