为什么PHP的uniqid函数只返回13位而不是14位?

Mar*_*aio 10 php unique-id

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

但是microtime以字符串格式返回数字如下:

"0.70352700 12689396875"
Run Code Online (Sandbox Code Playgroud)

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

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

我也想过取出"0".似乎永远不会改变的部分,以及似乎始终为"00"的microsec部分的最后两位数字.这样做十进制数字只有9 + 11-3位长,但是当转换成十六进制时仍然是十进制数字的17位数将导致14位十六进制数字不是13.

我不是有兴趣以另一种方式获得一个独特的ID或更长/更独特的ID!我只会问,如果有人知道为什么只能退回13个数字.

这似乎nosense:如果uniqid返回一个不到两位数microtime,这意味着microtime给出的结果是更独特返回的那些的uniqid.

KTa*_*phy 20

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

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

为了记录,uniqid()的基本功能似乎大致如下:

$ M = microtime中(真); 的sprintf( "%8X%05X \n" 个,地板($ M),($ M-地板($ M))*1000000);

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

日期( "R",hexdec(SUBSTR(uniqid(),0,8)));

随着时间的推移,随着时间的推移越来越多,数字随着时间的推移变得"更加独特",除了数字9,数字普遍性为0..3> 4> 5..f,因为10 ^ 6之间的差异和16 ^ 5(这可能对于其余的数字也是如此,但不太明显).


Pas*_*TIN 8

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

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


例如,使用这部分代码:

var_dump(uniqid());
var_dump(uniqid('', true));
Run Code Online (Sandbox Code Playgroud)

我刚得到 :

string '4ba284384e4ca' (length=13)
string '4ba284384e4df9.73439132' (length=23)
Run Code Online (Sandbox Code Playgroud)

  • Unix时间戳的秒数可以"适合"直到2106年2月初的8个十六进制字符((十六进制)`FFFFFFFF`是(dec)`4294967295`).微秒是百万分之一秒,所以最大的微秒值是"999999"(任何更大,它将是下一整秒)或十六进制的"F423F".所以:13个十六进制字符表示Unix时间到微秒. (2认同)