10

uniqid()函数返回一个 13 位长的十六进制数。根据php.net site 中的规范,该函数用于microtime生成唯一值。

microtime以字符串格式返回数字,如下所示:

"0.70352700 12689396875"

这基本上是自 1970 年以来经过的微秒和秒数。这是一个 9+11 位的十进制数。

将 20 位十进制数字转换为十六进制将导致16 位十六进制而不是 13 位数字。

我也想过要去掉“0”。似乎永远不会改变的部分,以及似乎始终保持“00”的微秒部分的最后两位数字。这样做,十进制数只有 9+11-3 位长,但仍然是 17 位的十进制数在转换为十六进制时会导致 14 位十六进制数不是 13。

我对以其他方式获得唯一 ID 或更长/更短的唯一 ID 不感兴趣!我只问是否有人知道为什么 uniqid 只返回 13 位数字。

这似乎是胡说八道:如果uniqid返回比 少一位microtime,这意味着microtime给出的结果比 .返回的结果更独特uniqid

4

4 回答 4

20

在http://www.php.net/manual/en/function.uniqid.php#95001上找到了这个

我感觉合理。如果您需要解释,请评论

作为记录,uniqid() 的底层函数大致如下:

$m=微时间(真);sprintf("%8x%05x\n",floor($m),($m-floor($m))*1000000);

换句话说,前 8 个十六进制字符 = Unixtime,后 5 个十六进制字符 = 微秒。这就是它具有微秒精度的原因。此外,它还提供了一种对生成 uniqid 的时间进行逆向工程的方法:

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

随着你越往下走,这个数字随着时间的推移变得越来越“独特”,除了数字 9,因为 10^6 之间的差异,数字普遍为 0..3>4>5..f和 16^5(这对于剩余的数字可能也是如此,但不太明显)。

于 2010-03-18T20:00:04.840 回答
8

我认为生成的数字uniqid基于当前时间(以微秒为单位)——但不是那个时间:计算可能比你想象的要难一些。

尽管如此,如果您需要超过 13 位数字,您可以true作为第二个参数传递给uniqid, 以获得更多的熵——它会给您一个 23 个字符长的字符串。


例如,使用这部分代码:

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

我刚得到 :

string '4ba284384e4ca' (length=13)
string '4ba284384e4df9.73439132' (length=23)
于 2010-03-18T19:50:50.443 回答
2

对于 32 个字符的唯一 ID,请尝试以下操作:

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

要缩短它,只需使用 substr():

$unique = substr(uniqid(rand(), true), 16, 16); // 16 characters long
于 2010-03-18T19:55:45.623 回答
-3

根据 PHP 手册,默认值为 13,将 $more_entropy 设置为 true,它将为 23,但您总是会得到一个 Unix 时间戳。

我经常用$uid = md5( uniqid() );

更新:
现在这将为您提供 32 个字符,并且一生中发生碰撞的可能性最小。

md5(uniqid(mt_rand(), true)); 
于 2010-03-18T19:56:45.920 回答