这个问题并不是在寻找解决方案,而只是一个简单的好奇。PHP中的uniqid函数有一个更高熵的标志,可以使输出“更加唯一”。这让我想知道,当more_entropy为真时,这个函数产生相同结果的概率有多大,与当它为假时相比如何呢?换句话说,启用more_entropy时uniqid有多独特,与禁用时相比如何?始终启用more_entropy有什么缺点吗?
这个问题并不是在寻找解决方案,而只是一个简单的好奇。PHP中的uniqid函数有一个更高熵的标志,可以使输出“更加唯一”。这让我想知道,当more_entropy为真时,这个函数产生相同结果的概率有多大,与当它为假时相比如何呢?换句话说,启用more_entropy时uniqid有多独特,与禁用时相比如何?始终启用more_entropy有什么缺点吗?
2014年3月更新:
首先,需要注意的是uniqid
有点名不副实,因为它不能保证唯一ID。
根据PHP文档:
警告!
此函数不会创建随机或不可预测的字符串。不得将此函数用于安全目的。使用具有加密安全性的随机函数/生成器和加密安全哈希函数创建不可预测的安全ID。
还有:
此函数不会生成具有加密安全性的令牌,事实上,如果没有传递任何其他参数,则返回值与microtime()几乎没有区别。如果需要生成具有加密安全性的令牌,请使用openssl_random_pseudo_bytes()。
将more-entropy设置为true可以生成更独特的值,但执行时间会更长(尽管很小),根据文档:
如果设置为TRUE,则uniqid()将在返回值的末尾添加其他熵(使用组合线性同余生成器),从而增加结果唯一的可能性。
请注意线条增加结果唯一的可能性
,而不是保证唯一性。
您可以无限地追求唯一性,到达某个点并使用任意数量的加密例程、添加salt等来增强-这取决于目的。
我建议查看主PHP主题上的评论,特别是:
http://www.php.net/manual/zh/function.uniqid.php#96898
http://www.php.net/manual/zh/function.uniqid.php#96549
http://www.php.net/manual/zh/function.uniqid.php#95001
我的建议是找出您需要唯一性的原因,是为了安全(例如添加到加密/混淆程序中)?此外,需要多独特?最后,考虑速度方面的问题。适用性将随着底层考虑而变化。
uniqid
(或其衍生版本)。 PHP提供了一整套安全的加密随机生成器,例如:openssl_random_pseudo_bytes
。请使用适合当前工作的正确工具。 - Halcyondo {} while(collision)
中。我在生成上传文件路径时也使用这种方法。 - afilina仅当您检查它们不存在时,事物才是独特的。无论您使用什么函数来生成“随机”字符串或ID-如果您不双重检查它是否重复,则总有那种可能性.. ;)
虽然uniqid基于当前时间,但上面的警告仍然适用-这取决于您将在哪里使用这些“唯一标识符”。所有这些的线索都在于“更加独特”的说法。独特就是独特。如何拥有更多或更少独特的东西,对我来说有点困惑!
按照上述方式进行检查,并结合所有这些内容,将使您得到接近唯一的东西,但这与密钥将被用于哪里和上下文有关。希望这有所帮助!
10^47
年才能有50%的概率出现冲突... 因此,是的,如果随机数的上限足够高并且随机数发生器足够好,则只需随机性即可模拟唯一性... - ircmaxellrand()
函数,那么在第一次迭代中就有超过90%的碰撞几率。此外,如果你需要唯一性,即使是0.001%的碰撞几率也太高了。 - cHao源代码中相关部分如下:链接
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位的熵,最多(实际上可能更少,因为LCG不是一个加密安全的伪随机数生成器)。uniqueId
的源代码后,可以清楚地看到其工作方式是将 1970-01-01 00:00:00 开始算起的微秒时间戳转换为一个ID。它还会等待一微秒的时间。$uniqueId = uniqid();
$uniqueId1 = uniqid();
more_entropy
标志,您可以确定$uniqueId != $uniqueId1
,因为每个ID始终是从不同的微秒生成的。uniqueid
可能不唯一。 如果是这种情况,则可以使用more_entropy
标志获取额外的29.9位熵。现在发生碰撞的概率非常小,甚至不值得检查该ID是否已存在。more_entropy
标志,否则请使用它。 如果需要加密安全的ID,则应使用一个不错的256位RNG。Ajax
或node.js
向服务器发出请求,就无法保证ID的唯一性。你想要实现什么? - Dan Bray如果你想生成一个唯一的ID,可以尝试这个方法。
$a = time();
$b = date("Ymd");
$c = uniqid();
$d = $asec + $bsec;
$e = $sku;
$gen = $a.'_'.$b.'_'.$c.'_'.$d.'_'.$e;
more_entropy
的uniqid
只提供约92位熵(23个十六进制位)。要了解为什么这不足以确保唯一性,请参阅“生日问题” 。 - ircmaxellmore_entropy
大约有30位熵(九个十进制数字),微秒部分大约有20位(六个十进制数字),其余的从哪里来的?你需要从10万年的范围内选择第二个才能获得42位的熵。 - Tgr