这个问题并不是一个寻找解决方案的问题,它只是一个简单的好奇心问题。PHP uniqid函数有一个more_entropy标志,使输出“更独特”。这让我想知道,当more_entropy为真时,与不为真时相比,这个函数多次产生相同结果的可能性有多大。换句话说,当more_entropy被启用时,与被禁用时相比,uniqid的唯一性如何?始终启用more_entropy有什么缺点吗?
mwyxok5s1#
如果没有more_unique标志,它将返回带有微秒计数器的unix时间戳,因此如果两个调用在同一微秒内进行,则它们将返回相同的“unique”id。接下来就是一个可能性有多大的问题了。答案是,不太可能,但也不会大打折扣。如果你“需要”一个唯一的id,而且你经常生成它们(或者使用其他地方生成的数据),不要指望它是绝对唯一的。
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不是加密安全的伪随机数生成器)。
more_entropy
php_combined_lcg()
(0,1)
yruzcnhs3#
在阅读uniqueId的source code之后,很明显,它的工作方式是将1970-01-01 00:00:00的时间(以微秒为单位)转换为ID。它还将等待一微秒。这意味着在下面的代码中:
uniqueId
$uniqueId = uniqid(); $uniqueId1 = uniqid();
即使没有more_entropy标志,也可以确定$uniqueId != $uniqueId1,因为每个ID总是从不同的微秒生成。如果ID是在不同的服务器上生成的,或者甚至是在同一个服务器上但在不同的线程上生成的,那么以微秒为单位的时间可能是相同的,因此uniqueid可能不是唯一的。如果是这种情况,那么您可以使用more_entropy标志来获得额外的29.9位的熵。现在冲突的可能性非常小。可能不值得检查以确保ID已经存在。如果你只在一台没有多线程php的服务器上生成ID,那么使用more_entropy标志是没有意义的,否则就使用它。如果你需要一个加密安全的ID,那么你应该使用一个体面的256位RNG代替。
$uniqueId != $uniqueId1
uniqueid
kq4fsx7k4#
2014年3月更新:
首先,必须注意uniqid有点用词不当,因为它不能保证唯一的ID。根据PHP documentation:
uniqid
警告!
此函数不会创建随机或不可预测的字符串。此函数不能用于安全目的。请使用加密安全的随机函数/生成器和加密安全的哈希函数来创建不可预测的安全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#96898http://www.php.net/manual/en/function.uniqid.php#96549http://www.php.net/manual/en/function.uniqid.php#95001我的建议是弄清楚 * 为什么 * 你需要唯一性,它是为了安全(例如,添加到加密/加扰例程)吗?还有,* 如何 * 它需要唯一性?最后,看看速度的考虑。适用性将随着潜在的考虑而改变。
increases the likelihood that the result will be unique
kjthegm65#
只有当你检查它们是否已经不存在时,它们才是唯一的。不管你用什么函数来生成一个“随机”字符串或ID --如果你不仔细检查它是否是重复的,那么总是有这种可能性的。)虽然uniqid是基于当前时间的,但上面的警告仍然适用--它只是取决于你将在哪里使用这些“唯一ID”。所有这一切的线索都是它说“更独特”的地方。独特就是独特就是独特。你怎么能拥有或多或少独特的东西,这让我有点困惑!如上所述进行检查,并将所有这些东西结合起来,会让你最终得到接近唯一性的东西,但这都是相对于键将被使用的位置和上下文而言的。希望这能有所帮助!
efzxgjgh6#
从PHP手册站点上关于函数的讨论中可以看出:正如下面的其他人所指出的,没有前缀也没有“添加的熵”,这个函数只是返回UNIX时间戳,并添加了十六进制数的微秒计数器;它或多或少只是十六进制形式microtime()。[...]另外值得注意的是,由于microtime()只在存在gettimeofday()〉的系统上工作,而Windows本身并不存在,因此uniqid()在Windows环境中可能只生成单秒分辨率的UNIX时间戳。换句话说,如果没有“more_entropy”,这个函数绝对是可怕的,永远不应该使用,句号。根据文档,这个标志将使用“组合线性同余生成器”来“添加熵”。嗯,这是一个相当弱的RNG。所以我会完全跳过这个函数,使用基于mt_rand的东西,为与安全无关的东西提供一个好的种子。而SHA-256则是用来证明的
6条答案
按热度按时间mwyxok5s1#
如果没有more_unique标志,它将返回带有微秒计数器的unix时间戳,因此如果两个调用在同一微秒内进行,则它们将返回相同的“unique”id。
接下来就是一个可能性有多大的问题了。答案是,不太可能,但也不会大打折扣。如果你“需要”一个唯一的id,而且你经常生成它们(或者使用其他地方生成的数据),不要指望它是绝对唯一的。
von4xj4u2#
源代码中的相关位为
因此
more_entropy
加上9个随机的十进制数字(php_combined_lcg()
返回(0,1)
中的值)--这最多是29.9位的熵(实际上可能更少,因为LCG不是加密安全的伪随机数生成器)。yruzcnhs3#
在阅读
uniqueId
的source code之后,很明显,它的工作方式是将1970-01-01 00:00:00的时间(以微秒为单位)转换为ID。它还将等待一微秒。这意味着在下面的代码中:
即使没有
more_entropy
标志,也可以确定$uniqueId != $uniqueId1
,因为每个ID总是从不同的微秒生成。如果ID是在不同的服务器上生成的,或者甚至是在同一个服务器上但在不同的线程上生成的,那么以微秒为单位的时间可能是相同的,因此
uniqueid
可能不是唯一的。如果是这种情况,那么您可以使用more_entropy
标志来获得额外的29.9位的熵。现在冲突的可能性非常小。可能不值得检查以确保ID已经存在。如果你只在一台没有多线程php的服务器上生成ID,那么使用
more_entropy
标志是没有意义的,否则就使用它。如果你需要一个加密安全的ID,那么你应该使用一个体面的256位RNG代替。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
我的建议是弄清楚 * 为什么 * 你需要唯一性,它是为了安全(例如,添加到加密/加扰例程)吗?还有,* 如何 * 它需要唯一性?最后,看看速度的考虑。适用性将随着潜在的考虑而改变。
kjthegm65#
只有当你检查它们是否已经不存在时,它们才是唯一的。不管你用什么函数来生成一个“随机”字符串或ID --如果你不仔细检查它是否是重复的,那么总是有这种可能性的。)
虽然uniqid是基于当前时间的,但上面的警告仍然适用--它只是取决于你将在哪里使用这些“唯一ID”。所有这一切的线索都是它说“更独特”的地方。独特就是独特就是独特。你怎么能拥有或多或少独特的东西,这让我有点困惑!
如上所述进行检查,并将所有这些东西结合起来,会让你最终得到接近唯一性的东西,但这都是相对于键将被使用的位置和上下文而言的。希望这能有所帮助!
efzxgjgh6#
从PHP手册站点上关于函数的讨论中可以看出:
正如下面的其他人所指出的,没有前缀也没有“添加的熵”,这个函数只是返回UNIX时间戳,并添加了十六进制数的微秒计数器;它或多或少只是十六进制形式microtime()。
[...]
另外值得注意的是,由于microtime()只在存在gettimeofday()〉的系统上工作,而Windows本身并不存在,因此uniqid()在Windows环境中可能只生成单秒分辨率的UNIX时间戳。
换句话说,如果没有“more_entropy”,这个函数绝对是可怕的,永远不应该使用,句号。根据文档,这个标志将使用“组合线性同余生成器”来“添加熵”。嗯,这是一个相当弱的RNG。所以我会完全跳过这个函数,使用基于mt_rand的东西,为与安全无关的东西提供一个好的种子。而SHA-256则是用来证明的