用PHP的uniqid()函数生成唯一URL令牌的简写形式是什么?

4
我需要一个函数,可以生成唯一的字母数字令牌,我想使用uniqid,但它对于用户友好的令牌来说太长了。我需要从uniqid字符串的末尾取多少位才能缩短长度,同时我可以在一秒钟内进行1000个请求(每毫秒1个)。我知道uniqid使用microtime()来计算字符串。这是否可能,还是我必须使用其他函数?如果我必须使用另一个函数,那么你能否给我展示一个或两个函数?谢谢!

请查看 openssl_random_pseudo_bytes - Valerij
有太多变量无法给出一个好的答案。这取决于您的服务器负载和其CPU容量等因素。要达到每秒1000个请求,需要从末尾削减多少内容取决于具体情况。 - halfer
@halfer,你能否给我一个建议的答案,告诉我我应该从末尾去掉多少个字符才不会使其变得非唯一? - user1558845
我需要从末尾去掉多少个字符才能保持唯一性?所有哈希都存在冲突(即将两个不同的东西哈希后得到相同的结果)。你缩短的越多,发生冲突的可能性就越大。你需要在方便用户的长度和避免冲突之间做出权衡,比如说8个字母数字字符(36^8)?或者,如果你愿意使用大小写敏感(62^8)。这仍然是很多URL,你需要为每一个URL查找数据库行。 - halfer
@halfer,echo substr(uniqid(), 0, 10);对于我告诉你的内容来说足够唯一了吗? - user1558845
那是16的10次方种组合。如果你的URL比这还少,那当然没问题!:) - halfer
2个回答

3

据看来,md4是最快的:http://www.php.net/manual/en/function.hash.php 但是生成32个字符。

crc32b 只有8个字符,并且仍然是最快的哈希之一。

echo hash('crc32b', 'http://stackoverflow.com');

这是luka8088发布的1000 Kb性能结果:

Results: (in microseconds)
   1.  md4                           5307.912
   2.  md5                           6890.058
   3.  crc32b                        7298.946
   4.  crc32                         7561.922
   5.  sha1                          8886.098
   6.  tiger128,3                    11054.992
   7.  haval192,3                    11132.955
   8.  haval224,3                    11160.135
   9.  tiger160,3                    11162.996
  10.  haval160,3                    11242.151
  11.  haval256,3                    11327.981
  12.  tiger192,3                    11630.058
  13.  haval128,3                    11880.874
  14.  tiger192,4                    14776.945
  15.  tiger128,4                    14871.12
  16.  tiger160,4                    14946.937
  17.  haval160,4                    15661.954
  18.  haval192,4                    15717.029
  19.  haval256,4                    15759.944
  20.  adler32                       15796.184
  21.  haval128,4                    15887.022
  22.  haval224,4                    16047.954
  23.  ripemd256                     16245.126
  24.  haval160,5                    17818.927
  25.  haval128,5                    17887.115
  26.  haval224,5                    18085.002
  27.  haval192,5                    18135.07
  28.  haval256,5                    18678.903
  29.  sha256                        19020.08
  30.  ripemd128                     20671.844
  31.  ripemd160                     21853.923
  32.  ripemd320                     22425.889
  33.  sha384                        45102.119
  34.  sha512                        45655.965
  35.  gost                          57237.148
  36.  whirlpool                     64682.96
  37.  snefru                        80352.783
  38.  md2                           705397.844

顺便说一下,delicious 曾经使用 MD5 对所有的 URI 进行加密(因此 delicious.com/md5hash 可以代表任何 URI)。


可能是http://en.wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions底部表格的结果。 - edelwater

0

你尝试过类似这样的东西吗?

$string = md5(rand()); 

如果太长,你可以使用substr()来缩短它。我发现这个方法非常快。

已经发现,hash('md5', 'string'); 比 md5($string) 更快(来源于 md5 php 页面) - edelwater
我是说独一无二性吗?感谢您的帮助。 - user1558845
MD5非常独特 - 输入中的一个字符更改将导致截然不同的哈希值。如果您想要更多的独特性,可以无限使用md5(rand() . rand()) - David
你可以使用 substr() 来缩短它。如果你想要20个字符,你可以这样做:substr(md5(rand()), 0, 20); - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接