Php 将microtime()与Sha1一起使用(生成唯一哈希)

Php 将microtime()与Sha1一起使用(生成唯一哈希),php,sha1,Php,Sha1,我打算在数据库中存储$hash 如果我一次又一次地将字符串输入到Sha1()中,它将生成相同的哈希值。但是如果我输入它microtime(),它返回当前的Unix时间戳(以微秒为单位),它是否会保证将来所有调用都使用不同的哈希值(因为当前时间将增加)。在这里,我假设将来的调用是对这个函数的调用,与上一次调用至少相差1分钟 你会怎么说 我知道我可以通过简单地检查数据库表中是否已经存在该散列来检查唯一性,但我只想知道当如上所述使用时,我是否可以假定它是唯一的。你能保证唯一性吗?否。SHA1生成160

我打算在数据库中存储$hash

如果我一次又一次地将字符串输入到
Sha1()
中,它将生成相同的哈希值。但是如果我输入它
microtime()
,它返回当前的Unix时间戳(以微秒为单位),它是否会保证将来所有调用都使用不同的哈希值(因为当前时间将增加)。在这里,我假设将来的调用是对这个函数的调用,与上一次调用至少相差1分钟

你会怎么说


我知道我可以通过简单地检查数据库表中是否已经存在该散列来检查唯一性,但我只想知道当如上所述使用时,我是否可以假定它是唯一的。你能保证唯一性吗?否。SHA1生成160位哈希。可以从
microtime
获得的值超过
2^160
。因此,将有多个值生成相同的散列。散列值将随机分布,因此即使在相对较小的时间间隔内也可能发生冲突


你能在实践中假设独特性吗?好吧,既然不能保证,那就是概率。强制执行最小间隔并没有帮助——任何两个观测值之间发生哈希冲突的概率都是相同的。但是概率很低,所以你可能没事。这取决于如果你得到了一个,世界是否会终结,或者你是否只会受到轻微的不便……;)

使用您不需要创建自己的

您可以确定它的唯一性,并使数据库中的列也唯一,以确保…这样您可以重新浏览…并且$rand()不能总是与microtime()相同。

您可以使用UUID(如本页上的注释所示:)然而,上面的UUID并不是一个UUID,所以您不能假设它是唯一的就插入它


你可以说有十亿分之一的可能发生冲突。如果你拿出
rand()
(因为这实际上会增加
time+rand
的可能性,等于发生了什么事情)并且只在时间上工作,这可以减少,但是这一切实际上取决于访问,我的意思是拿
MongoId
,基于时间,但如果访问和碎片足够多,则可能会发生冲突,并且确实……

绝对计算具有预定义有限长度字符串的哈希函数可以保证唯一性。任何这样的有限长度字符串都有有限数量的可能输出,但有无限数量的输入。看到任何散列函数都必须处理冲突并不复杂

也就是说,哈希字符串的长度越长,发生冲突的可能性就越大

您也可以使用guid或类似的东西,但这是同一个问题:存在冲突的可能性。极不可能,但有可能

如果您需要确保唯一性,请使用类似于
自动增量
,或其他类型的ID来确保唯一性

如果你只是想要一些看起来很复杂(但实际上并不复杂)的东西,那么。。。为什么?但是我想如果你已经下定决心了,试着做一些事情,比如在你的散列中填充唯一的ID,例如:

$hash = sha1(rand().microtime());
或:


sha1
没有任何随机性。你这是什么意思?你觉得Uniqid()@David怎么样?我的意思是散列值的分布实际上是随机的-你不需要在开始循环之前枚举
2^160
值。同意我的措辞是次优的-将进行编辑。与Uniqid的问题相同,如评论所示。它不能保证唯一性。但像这种方法一样,极不可能产生重复项。为什么不直接使用自动增量列呢?用时间戳哈希替换现有功能有什么意义?我需要一些复杂的外观,而不是简单的数字。你说你需要唯一的数字,自动增量是唯一的解决方案。然后你说你真的需要一些“复杂的外观”。这很令人沮丧:)@Tiberiu IonuțStan也许他正在寻找一个API密钥分发给个人,在这种情况下,自动增量是不够的。我的意思是,你在facebook for twitter或google上的应用程序ID是一个递增的ID吗?有很多理由不使用AI,正如OP所说:冷静…@Sammaye如果我们不必猜测,那就太好了。它能保证一个唯一的(不需要我检查唯一的)吗?每次你得到一个复制品(在现实世界中使用)我会给你一美元-这足够好吗?它不是“保证”,但“极不可能”哈哈-是的,这已经足够好了-而且在我的场景中极不可能是足够好了,有趣的一点是,如果去掉rand()是真的-因为我只是为了让它更独特而添加的-你知道我的意思:P@user1421214事实上,添加rand()(因为它是一个随机数)可以,但不太可能,使用
microtime()
组合时创建两个副本,因为您可以在将来获得一个组合日期,然后在将来某个时间获得一个rand(),该rand()给出一个较低的数字,并且它们相等,这不太可能,但我还是不会把我的钱押在上面。干杯@Sammaye-我要测试uniqid。干杯,伙计-我要用你的部分解决方案+1从我这里。:)
$hash = $id . sha1(rand().microtime());
$sha1 = sha1(rand().microtime());
$hash = substr($sha1,0,20). '-'.$id.'-'. substr($sha1,21);