2012-03-21 27 views
1

我在我的WWW框架中使用了大量API調用的緩存和緩衝,並且我最終使用的所有東西之一是'指紋'數據以匹配緩存文件名以及檢測已經完成的API調用。用於指紋數組的最快方法(從數據數組中計算唯一散列)

很多數據在數組中移動,如GET,POST等。因此,API調用的唯一性取決於數據。

因此,我需要指紋這些信息。要做到這一點,還需要從數據數組中生成一個「指紋」,並將其散列成一個可存儲和比較的字符串。

對於數組序列化,PHP中有serialize()和json_encode()。在各種基準測試之後,我認爲json_encode()是序列化數組的更快方法,我對此感到滿意。

對於散列有md5()和sha1()函數,其中md5()更快根據我的基準。

所以我目前的指紋算法是:

$fingerprint=md5(json_encode($array)); 

,但我有懷疑這是否是指紋識別PHP中的數組的「最快的」方法。我試過谷歌和StackOverflow,但沒有找到好的替代品。我在正確的軌道上還是需要做一些不同的事情?

+1

'md5(var_export($ data,true))'比較?另外 - 不知道你是否可以依靠命令來保存'json_encode'。錯過緩存會很糟糕,因爲按鍵順序不同。 – Hamish 2012-03-21 21:42:30

+2

根據我的測試,var_export()比serialize()快,但比json_encode()慢。我正在研究crc32()來替換md5(),需要測試。 – kingmaple 2012-03-21 21:46:25

+0

好吧,顯然(令我驚訝)crc32()實際上比md5()慢,當然更容易發生碰撞。所以我回到以前我在md5(json_encode($ array)); – kingmaple 2012-03-21 23:38:12

回答

3

一旦你得到了你的數組json_encoded,如果你主要關心速度,你應該使用非cyrptographic哈希函數。不同的散列函數適用於不同的事情。 MD5和Sha1被稱爲加密,因爲它們很難反轉(注意它們被廣泛認爲由於安全漏洞而被棄用)。 CRC(循環冗餘校驗)功能是錯誤檢測代碼,無論如何不適合獨特性。

如果僅僅因爲那裏的貢獻通常具有到庫實現的外部鏈接,維基百科是一個體面的開始。 List of hash functions我會推薦閱讀一些非加密庫並對其進行基準測試。非密碼函數更多地爲速度和合理的唯一性編寫,犧牲安全性,錯誤檢測和其他有趣的屬性,從您的描述中正是您想要的。

如果您主要關心速度,最後要注意的一點是如何存儲和比較指紋本身。 MD5輸出128位數據,在沒有額外的庫調用和開銷的情況下,它不適合php中的數字類型。對於我的錢,我敢打賭,你可以獲得最佳的比較速度,存儲將來自一個散列函數,可以直接輸出64位數字。請注意,要在php中本地獲取64位數字,您需要具有64位硬件,並且已經以64位模式配置/安裝了php。我在這裏有一些代碼,用於測試我們可以挖掘的分期和產品環境,如果你感興趣的話。

順便說一句,我不認爲你會得到比json-encode更快的數組串。這個問題的核心是數組行走和字符串操作,所以速度基本上與輸出的冗長度成正比。與PHP的序列化或導出功能相比,JSON編碼非常簡潔。我敢打賭,如果你在php文檔頁面上瀏覽了足夠多的評論,你可以找到一些人編寫了一個散列函數,它直接把一個數組作爲輸入,但是這是否是一件好事,這將是一場賭博。

隨意提問我什麼都不清楚。

+0

不是最好的答案,但考慮到情況就夠了。謝謝你的幫助! – kingmaple 2012-03-22 22:35:34

+3

其中一種情況是它的獨特之處,我會說它*是最好的答案。 – tiwo 2012-07-20 23:15:50

相關問題