php uniqid有多唯一?

ugmeyewa  于 2022-12-17  发布在  PHP
关注(0)|答案(6)|浏览(156)

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

mwyxok5s

mwyxok5s1#

如果没有more_unique标志,它将返回带有微秒计数器的unix时间戳,因此如果两个调用在同一微秒内进行,则它们将返回相同的“unique”id。
接下来就是一个可能性有多大的问题了。答案是,不太可能,但也不会大打折扣。如果你“需要”一个唯一的id,而且你经常生成它们(或者使用其他地方生成的数据),不要指望它是绝对唯一的。

von4xj4u

von4xj4u2#

源代码中的相关位为

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不是加密安全的伪随机数生成器)。

yruzcnhs

yruzcnhs3#

在阅读uniqueIdsource code之后,很明显,它的工作方式是将1970-01-01 00:00:00的时间(以微秒为单位)转换为ID。它还将等待一微秒。
这意味着在下面的代码中:

$uniqueId = uniqid();
$uniqueId1 = uniqid();

即使没有more_entropy标志,也可以确定$uniqueId != $uniqueId1,因为每个ID总是从不同的微秒生成。
如果ID是在不同的服务器上生成的,或者甚至是在同一个服务器上但在不同的线程上生成的,那么以微秒为单位的时间可能是相同的,因此uniqueid可能不是唯一的。如果是这种情况,那么您可以使用more_entropy标志来获得额外的29.9位的熵。现在冲突的可能性非常小。可能不值得检查以确保ID已经存在。
如果你只在一台没有多线程php的服务器上生成ID,那么使用more_entropy标志是没有意义的,否则就使用它。如果你需要一个加密安全的ID,那么你应该使用一个体面的256位RNG代替。

kq4fsx7k

kq4fsx7k4#

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
我的建议是弄清楚 * 为什么 * 你需要唯一性,它是为了安全(例如,添加到加密/加扰例程)吗?还有,* 如何 * 它需要唯一性?最后,看看速度的考虑。适用性将随着潜在的考虑而改变。

kjthegm6

kjthegm65#

只有当你检查它们是否已经不存在时,它们才是唯一的。不管你用什么函数来生成一个“随机”字符串或ID --如果你不仔细检查它是否是重复的,那么总是有这种可能性的。)
虽然uniqid是基于当前时间的,但上面的警告仍然适用--它只是取决于你将在哪里使用这些“唯一ID”。所有这一切的线索都是它说“更独特”的地方。独特就是独特就是独特。你怎么能拥有或多或少独特的东西,这让我有点困惑!
如上所述进行检查,并将所有这些东西结合起来,会让你最终得到接近唯一性的东西,但这都是相对于键将被使用的位置和上下文而言的。希望这能有所帮助!

efzxgjgh

efzxgjgh6#

从PHP手册站点上关于函数的讨论中可以看出:
正如下面的其他人所指出的,没有前缀也没有“添加的熵”,这个函数只是返回UNIX时间戳,并添加了十六进制数的微秒计数器;它或多或少只是十六进制形式microtime()。
[...]
另外值得注意的是,由于microtime()只在存在gettimeofday()〉的系统上工作,而Windows本身并不存在,因此uniqid()在Windows环境中可能只生成单秒分辨率的UNIX时间戳。
换句话说,如果没有“more_entropy”,这个函数绝对是可怕的,永远不应该使用,句号。根据文档,这个标志将使用“组合线性同余生成器”来“添加熵”。嗯,这是一个相当弱的RNG。所以我会完全跳过这个函数,使用基于mt_rand的东西,为与安全无关的东西提供一个好的种子。而SHA-256则是用来证明的

相关问题