uniqid有多独特?

时间:2010-11-01 15:08:12

标签: php

这个问题并不是寻找解决方案的问题,更多的只是一个简单的好奇心问题。 PHP uniqid函数有一个更多的熵标志,使输出“更独特”。这让我想知道,当more_entropy为真时,这个函数有多大可能产生相同的结果,而不是。换句话说,启用more_entropy与禁用more_entropy时,uniqid的唯一性如何?启用more_entropy是否有任何缺点?

5 个答案:

答案 0 :(得分:36)

更新,2014年3月:

首先,重要的是要注意uniqid有点用词不当,因为它不保证唯一ID。

根据PHP documentation

  

警告!

     

此函数不会创建随机字符串或不可预测字符串。这个   函数不得用于安全目的。使用加密方式   安全随机函数/生成器和加密安全散列   用于创建不可预测的安全ID。

  

此功能不会生成加密安全令牌   事实上没有传递任何额外参数的返回值   与microtime()略有不同。如果你需要生成   加密安全令牌使用openssl_random_pseudo_bytes()


将more-entropy设置为true会产生更独特的值,但执行时间更长(尽管程度很小),根据文档:

  

如果设置为TRUE,uniqid()将添加额外的熵(使用   返回结束时的组合线性同余生成器   值,这会增加结果唯一的可能性。

请注意第increases the likelihood that the result will be unique行,而不是保证唯一性。

你可以“无休止地”追求独特性,达到一定程度,并增强使用任意数量的加密例程,添加salts等等 - 这取决于目的。

我建议查看主要PHP主题的评论,特别是:

http://www.php.net/manual/en/function.uniqid.php#96898

http://www.php.net/manual/en/function.uniqid.php#96549

http://www.php.net/manual/en/function.uniqid.php#95001

我建议的是为什么你需要唯一性,是为了安全性(即添加到加密/加扰例程)?此外,还需要如何独特?最后,看看速度考虑。适用性将随着潜在的考虑而改变。

答案 1 :(得分:15)

只有当你检查它们不存在时,事物才是唯一的。使用什么函数生成“随机”字符串或ID并不重要 - 如果你不仔细检查它是不是重复,那么总有那种机会......;)

虽然uniqid基于当前时间,但上面的注意事项仍然适用 - 它只取决于您将使用这些“唯一ID”的位置。这一切的线索就是“更独特”的地方。独特是独一无二的。你怎么能拥有或多或少独特的东西,对我来说有点混乱!

如上所述进行检查,并结合所有这些内容将让您最终得到一些接近唯一性的东西,但这些都与密钥的使用位置和上下文有关。希望有所帮助!

答案 2 :(得分:10)

关于PHP手册网站上的功能的讨论:

  

如下所示,没有前缀   没有“添加熵”,这个   函数只返回UNIX   添加微秒的时间戳   计数器为十六进制数;它更多或   更少只是microtime(),以hexit形式。

     

[...]

     

另外值得注意的是,由于microtime()仅适用于具有gettimeofday()>的系统。目前,Windows本身没有,uniqid()可能只会在Windows环境中产生单秒分辨率的UNIX时间戳。

换句话说,没有“more_entropy”,这个函数绝对可怕,永远不应该使用,句号。根据文档,该标志将使用“组合线性同余生成器”来“添加熵”。嗯,这是一个相当弱的RNG。所以我完全跳过这个函数并使用基于mt_rand的东西和一些非安全相关的东西,以及用于东西的SHA-256。

答案 3 :(得分:7)

如果没有more_unique标志,它会返回带有微秒计数器的unix时间戳,因此如果两个调用以相同的微秒进行,那么它们将返回相同的“唯一”ID。

从那里开始,这是一个多么可能的问题。答案是,不是很好,但不是折扣程度。如果您需要一个唯一ID并且您经常生成它们(或使用其他地方生成的数据),请不要指望它绝对唯一。

答案 4 :(得分:4)

来自the source code的相关位是

if (more_entropy) {
    uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10);
} else {
    uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec);
}

所以more_entropy添加了9个有点随机的十进制数字(php_combined_lcg()返回(0,1)中的值) - 这是29.9位的熵,tops(实际上可能更少,因为LCG不是加密的安全的伪随机数发生器)。