2012-08-06 77 views
0
$hash = sha1(rand().microtime()); 

我打算存储在数据库$哈希值。(产生唯一的哈希)

如果我一次又一次输入一个字符串到Sha1()它会产生相同的散列。但是,如果我输入它microtime()它返回当前的Unix时间戳与微秒 - 它保证所有未来呼叫(当前时间将增加)不同的散列。我在这里假定未来的呼叫是在前一次呼叫之后至少1分钟的时间内对此功能进行的呼叫?

你会说什么?

我知道我可以通过简单地检查这个哈希是否已经存在于数据库表中来检查唯一性,但是我只是想知道是否可以像上面那样使用它的独特性。

+0

为什么不直接使用AUTO_INCREMENT列?用时间戳散列替换现有功能有什么意义? – 2012-08-06 09:40:43

+0

我需要一些比普通数字更复杂的外观。 – user1421214 2012-08-06 09:41:52

+0

你说你需要唯一的号码,AUTO_INCREMENT是唯一的解决方案。然后你说你实际上需要一些“复杂的外观”。这是非常令人沮丧:)) – 2012-08-06 09:51:48

回答

2

你能保证唯一性?编号SHA1产生一个160位散列。有多于2^160可能的值可从microtime获得。因此会有多个值生成相同的散列值。散列值将根据所有意图和目的随机分布,所以即使在相对较小的时间间隔内也可能发生冲突。

你可以假设在实践中是唯一的吗?那么,既然没有保证,那全是概率。这对于强制执行最小间隔没有帮助 - 任何两次观察之间散列冲突的概率是相同的。但可能性很低,所以你可能会好起来的。取决于如果你得到一个世界是否会结束,或者如果你只是被minorly不便...;)

+0

关于'sha1'没有任何随机。你是什​​么意思? – Esailija 2012-08-06 09:38:44

+0

你觉得Uniqid()@David怎么样? – user1421214 2012-08-06 09:56:04

+1

我的意思是散列值的分布是有效的随机 - 你不需要在开始回收之前枚举'2^160'值。同意我的措辞是不理想的 - 将编辑。 – 2012-08-06 09:56:38

2

使用uniqid()你不需要创建自己的

+0

它会保证一个独特的(不需要我检查唯一)? – user1421214 2012-08-06 09:42:31

+0

每次你得到一个副本(在你的现实世界中使用)时,我给你一块钱 - 足够好了吗? – 2012-08-06 09:43:35

+0

它不是“保证”,但“极不可能” – cegfault 2012-08-06 09:46:54

0

你可以肯定的.. ...的独特性,并使db中的列具有唯一性以确保...以便您可以重新抛出...和$ rand()不能总是和microtime一样()

1

您可以使用UUID(如本页的评论所示:http://php.net/manual/en/function.uniqid.php)但上述内容不是UUID,因此您不能只是假设它是唯一的。

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

+0

有趣的点,如果其真正的关于采取出RAND() - 作为我只加,使之更加独特的 - 你知道我的意思:P – user1421214 2012-08-06 09:44:11

+0

@ user1421214事实上,加入兰特()(因为它是一个随机数)就可以了,非常不可能的,但可以当'microtime中由创建两个副本() '因为你可以在未来获得一个包含日期,那么有一个RAND()在未来某个时候,给出了一个较低的数量和繁荣,他们等于相同,不太可能会,但仍散......我不会打赌我的钱那。 – Sammaye 2012-08-06 09:50:06

+0

欢呼@Sammaye - 我要测试uniqid。 – user1421214 2012-08-06 10:03:42

1

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

这就是说,散列字符串的大小越长,发生碰撞的可能性就越小。

您也可以使用GUID或uniqid之类的东西,但问题同样存在:存在碰撞的可能性。极不可能,但可能。

如果您需要保证是唯一的东西,请使用类似AUTO_INCREMENT或其他类型的ID以确保唯一性。

如果你只是想看起来复杂(但实际上不是),那么......为什么?但我想,如果你对死心塌地,尝试做类似馅的唯一ID到您的哈希值,例如:

$hash = $id . sha1(rand().microtime()); 

或:

$sha1 = sha1(rand().microtime()); 
$hash = substr($sha1,0,20). '-'.$id.'-'. substr($sha1,21); 
+0

欢呼队友 - 我会用你的解决方案的一部分。从我+1。 :) – user1421214 2012-08-06 10:02:45