为什么 PHP 的 uniqid 函数只返回 13 位而不是 14 位?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2472890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:36:21  来源:igfitidea点击:

Why does PHPs uniqid function return only 13 digits and not 14?

phpunique-id

提问by Marco Demaio

uniqid()function returns a 13 digits long hexadecimal number. According to the spec in php.net site, the function uses microtimeto generate the unique value.

uniqid()函数返回一个 13 位长的十六进制数。根据php.net 站点中规范,该函数用于microtime生成唯一值。

But microtimereturns numbers in string format as the following one:

microtime以字符串格式返回数字如下:

"0.70352700 12689396875"

which are basically the microseconds and the seconds elapsed since 1970. This is a 9+11 digits decimal number.

这基本上是自 1970 年以来经过的微秒和秒数。这是一个 9+11 位的十进制数。

Converting a 20 decimal number into hex would result in a 16 digits hexadecimal NOT a 13 digits one.

将 20 位十进制数转换为十六进制将导致16 位十六进制数而不是 13 位十六进制数。

I also thought to take out the "0." part that seem to never change, and the last two digits of the microsec part that seem to remain always "00". Doing this the decimal number would be only 9+11-3 digits long, but still a decimal number of 17 digits when converted into hex would result in 14 digits hexadecimal number NOT 13.

我还想把“0”去掉。似乎永远不会改变的部分,以及似乎始终保持“00”的微秒部分的最后两位数字。这样做十进制数将只有 9+11-3 位长,但转换为十六进制时仍然是 17 位的十进制数将导致 14 位十六进制数而不是 13。

I'M NOT INTERESTED IN GETTING A UNIQUE ID IN ANOTHER WAY OR A LONGER/SHORTER UNIQUE ID! I'M ONLY ASKING IF SOMEONE KNOWS WHY DOES uniqid RETURNS ONLY 13 DIGITS.

我对以其他方式获得唯一 ID 或更长/更短的唯一 ID 不感兴趣!我只是问是否有人知道为什么 uniqid 只返回 13 位数字。

It seems nosense: if uniqidreturns one digit less than microtime, it means that microtimegives out results that are more uniqueof the ones returned by uniqid.

这似乎nosense:如果uniqid返回一个数字小于microtime,这意味着microtime给出的结果是更独特返回的那些的uniqid

回答by KTastrophy

Found this on http://www.php.net/manual/en/function.uniqid.php#95001

http://www.php.net/manual/en/function.uniqid.php#95001上找到了这个

Makes sense to me. Comment if you need an explanation

我感觉合理。如果您需要解释,请发表评论

For the record, the underlying function to uniqid() appears to be roughly as follows:

$m=microtime(true); sprintf("%8x%05x\n",floor($m),($m-floor($m))*1000000);

In other words, first 8 hex chars = Unixtime, last 5 hex chars = microseconds. This is why it has microsecond precision. Also, it provides a means by which to reverse-engineer the time when a uniqid was generated:

date("r",hexdec(substr(uniqid(),0,8)));

Increasingly as you go further down the string, the number becomes "more unique" over time, with the exception of digit 9, where numeral prevalence is 0..3>4>5..f, because of the difference between 10^6 and 16^5 (this is presumably true for the remaining digits as well but much less noticeable).

作为记录,uniqid() 的底层函数似乎大致如下:

$m=微时间(真);sprintf("%8x%05x\n",floor($m),($m-floor($m))*1000000);

换句话说,前 8 个十六进制字符 = Unixtime,最后 5 个十六进制字符 = 微秒。这就是它具有微秒精度的原因。此外,它还提供了一种对生成 uniqid 的时间进行逆向工程的方法:

date("r",hexdec(substr(uniqid(),0,8)));

随着字符串越往下走,该数字会随着时间的推移变得“更加独特”,但数字 9 除外,由于 10^6 之间的差异,数字流行率为 0..3>4>5..f和 16^5(对于其余的数字,这可能也是正确的,但不太明显)。

回答by Pascal MARTIN

I think the number generated by uniqidis based onthe current time in microseconds -- but it is not that time : the calculation is probably a bit harder that you think.

我想,通过所产生的数量uniqid基于以微秒当前时间-但它不是时间:计算可能有点困难,你认为。

Still, if you need more than 13 digits, you can pass trueas a second parameter to uniqid, to have more entropy -- and it'll give you a string that's 23 characters longs.

尽管如此,如果您需要超过 13 个数字,您可以将true第二个参数作为第二个参数传递给uniqid, 以获得更多的熵——它会给您一个长度为 23 个字符的字符串。


For instance, with this portion of code :


例如,使用这部分代码:

var_dump(uniqid());
var_dump(uniqid('', true));

I just got :

我刚得到 :

string '4ba284384e4ca' (length=13)
string '4ba284384e4df9.73439132' (length=23)

回答by John Conde

For a 32 character unique ID try this:

对于 32 个字符的唯一 ID,试试这个:

$unique = uniqid(rand(), true);

To shorten it just use substr():

要缩短它,只需使用 substr():

$unique = substr(uniqid(rand(), true), 16, 16); // 16 characters long

回答by Michael D. Irizarry

Per the PHP manual the Default is 13 with the $more_entropy set to true it will be 23, but you will always end up with a Unix Timestamp.

根据 PHP 手册,默认值是 13,$more_entropy 设置为 true,它将是 23,但最终会得到 Unix 时间戳。

I often use $uid = md5( uniqid() );

我经常用 $uid = md5( uniqid() );

Update:
Now this will give you 32 characters with a minimal chance of collision is this lifetime.

更新:
现在这将为您提供 32 个字符,并且此生的碰撞机会最小。

md5(uniqid(mt_rand(), true));