2012-08-06 83 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