Php uniqid有多独特?

Php uniqid有多独特?,php,Php,这个问题并不是一个寻找解决方案的问题,它更只是一个简单的好奇心问题。PHP uniqid函数具有更高的熵标志,以使输出“更独特”。这让我想知道,当更多的熵为真时,这个函数多次产生相同结果的可能性有多大。换句话说,当启用更多的熵时,uniqid与禁用时相比有多独特?一直启用更多的_熵有什么缺点吗 更新,2014年3月: 首先,需要注意的是,uniqid有点用词不当,因为它不能保证唯一的ID 根据: 警告 此函数不会创建随机或不可预测的字符串。这 函数不得用于安全目的。加密使用 安全随机函数/生成器

这个问题并不是一个寻找解决方案的问题,它更只是一个简单的好奇心问题。PHP uniqid函数具有更高的熵标志,以使输出“更独特”。这让我想知道,当更多的熵为真时,这个函数多次产生相同结果的可能性有多大。换句话说,当启用更多的熵时,uniqid与禁用时相比有多独特?一直启用更多的_熵有什么缺点吗

更新,2014年3月:

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

根据:

警告

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

在中,此函数不生成加密安全令牌 不向返回值传递任何附加参数的事实 这和我的想法没什么不同。如果需要生成 加密安全令牌使用


根据文档,将“更多熵”设置为“真”会生成一个更独特的值,但是执行时间更长(虽然只有很小的程度):

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

注意,
行增加了结果唯一的可能性,而不是保证唯一性

您可以“无休止地”在一定程度上争取唯一性,并使用任意数量的加密例程、添加等来增强—这取决于目的

我建议大家看看关于PHP主题的评论,特别是:


我的建议是找出您需要唯一性的原因,是否出于安全考虑(即添加到加密/加扰例程)?另外,它需要有多独特?最后,看看速度方面的考虑。适用性将随着基础考虑因素的变化而变化。

如果没有more_unique标志,它将返回带有微秒计数器的unix时间戳,因此如果在同一微秒进行两个调用,则它们将返回相同的“unique”id


从这里开始,问题是这种可能性有多大。答案是,不太可能,但也不到可以打折的程度。如果您需要一个唯一的id,并且您经常生成它们(或者处理在其他地方生成的数据),那么不要指望它是绝对唯一的。

只有检查它们是否已经存在,事情才是唯一的。使用什么函数生成“随机”字符串或ID并不重要——如果不仔细检查它是否重复,那么总是有这种可能性的……)

虽然uniqid是基于当前时间的,但上面的注意事项仍然适用——这取决于您将在何处使用这些“唯一ID”。所有这一切的线索是它说的“更独特”。独一无二的是独一无二的。你怎么能拥有一些或多或少独一无二的东西,这让我有点困惑


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

从PHP手册网站上关于函数的讨论中:

正如下面其他人所指出的,没有前缀 在没有“附加熵”的情况下 函数只返回UNIX 加上微秒的时间戳 计数器作为十六进制数;差不多 不只是microtime(),以十六进制形式

[……]

另外值得注意的是,由于microtime()只在存在gettimeofday()>的系统上工作,而Windows本机没有,因此uniqid()在Windows环境中可能只产生一个秒分辨率的UNIX时间戳

换句话说,如果没有“更大的熵”,这个函数是绝对可怕的,永远不应该被使用。根据文件,该标志将使用“组合线性同余生成器”来“添加熵”。嗯,这是一个相当弱的RNG。因此,我将完全跳过此函数,并使用基于良好种子的内容来处理与安全无关的内容,使用SHA-256来处理与安全无关的内容。

中的相关位是


因此,
more\u entropy
添加了九个随机的十进制数字(返回
(0,1)
中的值)-这是29.9位的最大熵(实际上可能更少,因为LCG不是一个加密安全的伪随机数生成器)。

如果您想要总是唯一的东西,您需要实现一个。因为函数中只有这么多的熵,所以几乎所有的东西最终都会发生碰撞。例如,
uniqid
with
more_entropy
set只给出大约92位的熵(23个六位)。要理解为什么这不利于独特性,请参阅…@ircmaxell谢谢你指出生日问题,这很有趣。答案中应该明确提到它。uniqid()不是哈希函数,因此生日问题不适用于它。但是它确实有它的漏洞。@ircmaxell这个数字来自哪里<代码>更多的熵
大约是30位的熵(9位十进制数字),微秒部分大约是20位(6位十进制数字),其余的从何而来?你需要从10万年的范围中选取第二个,才能得到42位的熵。在“发生碰撞的概率是万分之一”和“发生碰撞的变化小于程序的每个用户同时被闪电击中”之间存在着巨大的差异。由一个好的RNG和一个好的种子生成的128位值非常接近于“真正”唯一
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);
}