2013-09-26 49 views
1

我在頁面上有一個textarea元素,點擊我創建的保存按鈕後,它的內容會保存到我的數據庫中。我希望使用表格行的唯一ID(主鍵)創建包含像「MySite.com/laHquq」這樣的短網址,其中我保存了包含textarea中的信息的記錄,該記錄包含:http://www.hashids.org/「將生成來自數字(如YouTube和Bitly)的短暫哈希。「我想用它來模糊包含textarea信息的記錄的錶行唯一主鍵。我是否避免使用此解決方案進行哈希碰撞?

我將有一個腳本將地址欄中的域名末尾的正斜槓後的哈希值創建(這是模糊主鍵),因此地址欄現在將具有:「MySite .com/laHquq「後信息被保存到我的數據庫。這只是簡單地做,以表明現在保存在textarea中的信息可以通過訪問帶有正斜槓後面的哈希值的站點再次看到。

我還會有一個腳本自我調用函數,每次頁面加載時都會從地址欄獲取url,並在正斜槓之後檢查哈希值,然後使用哈希id從中找到正確的信息數據庫顯示在頁面的textarea上。我想知道是否使用hashids:http://www.hashids.org/將有助於防止散列衝突。

+0

我這麼認爲。還有[其他方式](http://stackoverflow.com/questions/1771397/jquery-on-the-fly-url-shortener)。 –

回答

3

從文檔看來,您將永遠不會面對與hashid的衝突。那是因爲它不是哈希。這是一個密碼 - 一種加密算法。雖然很弱,但足以生成看起來像散列的ID。

一個關鍵線索是,有一個decrypt函數。真正的哈希,可以碰撞的哈希,不能被解密爲單個值,因爲有多個值(通常是無限)會生成相同的哈希值。

在某些方面,它與base64編碼相似,但字符集選擇爲URL友好(不是+/)。

+0

非常感謝Slebetman – user2801524

0

在此處顯示PHP的經驗結果。 我們已經與至少5個字符的,與此鹽測試如下所示:

$hashids = new Hashids\Hashids('this is my salt', 5, 'BCDFGHJKLMNPQRSTVWXYZ'); 

隨着在一個循環,以填補在MySQL DB行運行一週全天候的方法,從1散列PK,在一個表是這樣的:

create table hashids (
    id int NOT NULL AUTO_INCREMENT primary key, 
    hash varchar(255) 
); 

與哈希唯一索引,並同時控制腳本時對重複KEY並運行在的完整性檢查過程結束一個SELECT DISTINCT。

我們停止了該過程在

select count(*) from hashids; 
+-----------+ 
| count(*) | 
+-----------+ 
| 355325777 | 
+-----------+ 

於是我們決定從接近簽署BIGINT的上限開始。

ID: 9223372036854775000-> HASH: RQ0ZPNPPPZ6Q7RNV 
ID: 9223372036854775329-> HASH: YN2K8Y888K7NW6VY 
ID: 9223372036854775654-> HASH: 2MQ0474440VM8QMY 
ID: 9223372036854775777-> HASH: 7L25R7RRR5ZL820W 
ID: 9223372036854775805-> HASH: 020WV7VVVWX250YM 
ID: 9223372036854775807-> HASH: QVMZYRYYYZXVLM0W 

在這兩種情況下,運行了幾天並填充了15GB的ID後,hashid站了起來。

我們確認迄今沒有發現碰撞。

這個測試已經超出了我們的應用範圍,所以我們認爲Hashids對我們來說是安全的。當然,正如在數學中一樣,經驗結果並不能證明法律。

還要記住,在達到簽名/未簽名的BIGINT MySQL數據庫限制或PHP_INT_MAX之前,Hashids有一個上限,至少使用PHP。