2010-03-18 60 views
9

uniqid()函数返回一个13位长的十六进制数。根据spec in php.net site,函数使用microtime来生成唯一值。为什么PHP的uniqid函数只返回13位而不是14?

microtime但以字符串格式返回数字作为下列之一:

"0.70352700 12689396875" 

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

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

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

我不感兴趣IN以另一种方式获取唯一ID或更长/更短的唯一ID!我只是问,如果有人知道为什么uniqid返回只有13个数字。

似乎nosense:如果低于microtimeuniqid返回一个数字,它意味着microtime给出的结果是更加独特的uniqid返回者的

+0

你应该使用more_entropy选项,它给你一个更独特的结果。 – 2010-03-18 19:52:25

+1

不需要更多独特的,我需要知道为什么结果只有13个字符长。无论如何感谢您的建议。 – 2010-03-18 19:55:45

+0

microtime最显着的位并不经常。所以当你试图在彼此的几毫秒内产生两个独特的字符串时,它们是无用的。下一周的所有时间戳将从126开始。而且,如果您设法在相同的微秒内调用两次uniqid()(两个不同的线程或两个不同的服务器),您会发现其结果不会很独一无二。 – 2010-03-18 20:08:34

回答

19

发现这对http://www.php.net/manual/en/function.uniqid.php#95001

对我来说很有意义。注释如果你需要一个解释

为了记录在案,底层 函数uniqid()似乎是 大致如下:

$ M = microtime中(真); (“%8x%05x \ n”,floor($ m),($ m-floor($ m))* 1000000);

换句话说,前8个十六进制字符= Unixtime,最后5个十六进制字符= 微秒。这就是为什么它具有 微秒精度。此外,它提供了 借以 反向工程时产生一个 uniqid的时间的装置:

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

越来越多,你再下去 字符串,数字变得“更加 独特的”随着时间的推移,除数字9,其中数字患病 是0..3> 4> 5..f的 ,因为10^6和16^5之间的差异为 (这个 大概对于其余的 数字也是如此,但是更不明显的是 )。

7

我认为uniqid产生的数字是基于当前时间在微秒- 但它不是时间:计算可能有点困难,你认为。

但是,如果您需要超过13位数字,则可以将true作为第二个参数传递给uniqid,以获得更多熵 - 并且它会给您一个长度为23个字符的字符串。


例如,对于代码的这一部分:

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

我刚:

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

这并不回答我的问题,关键还是为什么uniqid函数返回一个只有13个字符长的值。由于缺少数字,因此它不能像microtime()函数那样唯一。无论如何感谢您的建议。 – 2010-03-18 20:03:37

+2

一个Unix时间戳的秒数可以'拟合'到2106年2月初的8个十六进制字符((hex)'FFFFFFFF'为(dec)'4294967295')。一微秒是百万分之一秒,所以最大微秒值是'999999'(任何大一点,它将是下一个整秒)或十六进制的'F423F'。所以:13个十六进制字符表示Unix时间到微秒。 – salathe 2010-03-18 21:58:31

0

为32个字符的唯一ID试试这个:

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

要缩短它只是使用substr():

$unique = substr(uniqid(rand(), true), 16, 16); // 16 characters long 
+4

这不会严重影响重复的机会吗? – Tom 2010-03-18 19:57:39

+0

机会仍然非常小,几乎不可能发生。但是,如果目标是确保最大独特性,则应使用整个MD5。 – 2010-03-18 20:09:26

+2

您正在添加角色,但减少了熵和唯一性。 – 2010-03-18 20:12:05

-3

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

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

更新:
现在,这将给你一个与碰撞的机率很少32个字符是此生。

md5(uniqid(mt_rand(), true)); 
+4

'md5()'根本不会引入任何更多的熵。如果有的话,它会消除一点,因为散列冲突的可能性很小。 – 2010-03-18 20:10:26

+1

'md5'不是碰撞抵抗,不应该用于此 – Petah 2010-10-28 02:14:04

+0

对不起,我完全忘了添加完整的示例md5(uniqid(mt_rand(),true)); uniqid是一个有更多的熵。 – 2012-04-05 15:11:24

相关问题