Search code examples
phpcunique-idgettimeofdaytimeval

questions related to source code of PHP uniqid()


In PHP source code function uniqid() have following C code: (I removed some types to shorten it)

//...
struct timeval tv;
gettimeofday(&tv, NULL);
int sec  = (int) tv.tv_sec;
int usec = (int) (tv.tv_usec % 0x100000);

// The max value usec can have is 0xF423F,
// so we use only five hex digits for usecs.
printf("%08x%05x", sec, usec);
//...

If we put criticism aside, they try to produce 64 bit timestamp.

0xF423F is probably CLOCKS_PER_SEC - 1 (CLOCKS_PER_SEC is decimal 1000000),

but where this 0x100000 come from and what could be the reason to use modulus instead of bitwise and?


Solution

  • She or he could write the Unique ID as printf("%08x%08x", sec, usec)

    sample output:
    55189926000eb16f
    5518997900051219
    5518997a0005171b
    

    The zeros in position 8 to 10 are consistent, they don't add entropy, so he wants to get rid of those zeros. The new UID will be 3 bytes shorter with the same entropy. He could simply use printf("%08x%05x", sec, usec);

    sample output:
    55189926eb16f
    5518997951219
    5518997a5171b
    

    But that's on the assumption that usec is guaranteed to be less than 0x100000 otherwise UID will be up to 16 bytes long. You need % 0x100000 for insurance. It's also the same as & 0xFFFFF. Technically the insurance should be % 1000000 (decimal), but it doesn't really matter, it's still the same entropy.

    Or we could just use the 16 byte version because saving 3 lousy bytes don't matter these days.