这个问题并不是寻找解决方案的问题,更多的只是一个简单的好奇心问题。 PHP uniqid函数有一个更多的熵标志,使输出“更独特”。这让我想知道,当more_entropy为真时,这个函数有多大可能产生相同的结果,而不是。换句话说,启用more_entropy与禁用more_entropy时,uniqid的唯一性如何?启用more_entropy是否有任何缺点?
答案 0 :(得分:36)
更新,2014年3月:
首先,重要的是要注意uniqid
有点用词不当,因为它不保证唯一ID。
警告!强>
此函数不会创建随机字符串或不可预测字符串。这个 函数不得用于安全目的。使用加密方式 安全随机函数/生成器和加密安全散列 用于创建不可预测的安全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不是加密的安全的伪随机数发生器)。