В исходном коде PHP функция uniqid () имеет следующий C-код:
(Я удалил некоторые типы, чтобы сократить его)
//...
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);
//...
Если оставить в стороне критику, они попытаются создать 64-битную временную метку.
0xF423F возможно CLOCKS_PER_SEC — 1 (CLOCKS_PER_SEC — десятичное 1000000),
но где это 0x100000 откуда и что может быть причиной для использования модуля вместо побитового и?
Она или он может написать уникальный идентификатор как printf("%08x%08x", sec, usec)
sample output:
55189926000eb16f
5518997900051219
5518997a0005171b
Нули в позициях с 8 по 10 последовательны, они не добавляют энтропию, поэтому он хочет избавиться от этих нулей. Новый UID будет на 3 байта короче с той же энтропией. Он мог просто использовать printf("%08x%05x", sec, usec);
sample output:
55189926eb16f
5518997951219
5518997a5171b
Но это при условии, что usec гарантированно будет меньше 0x100000, иначе UID будет иметь длину до 16 байт. Тебе нужно % 0x100000
для страховки. Это так же, как & 0xFFFFF
, Технически страховка должна быть % 1000000 (decimal)
, но это на самом деле не имеет значения, это все та же энтропия.
Или мы могли бы просто использовать 16-байтовую версию, потому что сохранение 3 паршивых байтов не имеет значения в наши дни.
Других решений пока нет …