2013-07-12 38 views
0

我需要創建設置長度的唯一且隨機的字母數字標識。理想情況下,我會在我的數據庫中存儲一個從0開始的計數器,並且每當我需要一個唯一的ID時,我將得到計數器值(0),通過這個哈希函數運行它,給它一個設定的長度(可能爲4-6個字符) ID = Hash(Counter,4);],它會返回我的新ID(例如7HU9),然後增加我的計數器(0 ++ = 1)。指定長度唯一ID生成

我需要保持身份證的簡短,以便他們可以很容易地被記住或分享。安全性不是一個大問題,所以我不擔心試用隨機ID的人,但我不希望ID是可預測的,所以用戶不可能有機會注意到ID的增量3每次只允許他們通過ID後退,並逐一下載ID數據(例如A5F9,A5F6,A5F3,A5F0 == BAD)。

我不想只循環檢查唯一性的隨機字符串,因爲隨着密鑰的用完,這會隨着時間的推移增加數據庫負載。其目的是散列一個唯一的遞增計數器將保證ID唯一性達到某個計數器值,此時生成的ID的長度將增加1並且計數器復位,並且永久地繼續該模式。

是否有人知道任何適合這種需求的散列函數,或者有任何其他想法?

編輯:我不需要能夠反轉函數來獲取計數器值。

回答

0

(這是前一段時間,但我應該寫了一下我落得這樣做......)

我想出了其實很簡單的想法。我想要字母數字引腳,這樣每個字符就能產生36個潛在字符,並且我想從4個字符引腳開始,這樣就可以達到36^4 = 1,679,616個可能的引腳。我意識到,我想要做的就是把所有這些可能的針腳都拿掉,然後以隨機的方式丟掉一部分,這樣人類隨機找到一個的機率就很低。因此,我將1,679,616除以100,然後將我的計數器乘以1和100之間的隨機數,然後將該數字編碼爲我的字母數字引腳。問題解決了!

通過猜測4個字母和數字的隨機組合,你有100分之一的機會真正猜測一個真正使用的針腳,這是我真正想要的。在我的實現中,一旦可用引腳空間耗盡,我會增加引腳長度,並且一切都很完美!已經跑了大約2年了!

1

就像你意識到的那樣,困難的部分是保證不碰撞序列。如果「不明顯」是猜測算法所需的標準,那麼一個簡單的全週期混合同餘RNG - 或者說它們的一個隨着時間的推移而增加模數以滿足增長要求的序列 - 可能就是你想。這不是你要求的哈希方法,但它應該工作。

This presentation涵蓋了MCRNG的基本知識和足夠的條件爲一個非常簡潔的形式的整個期間。還有很多其他的。

您首先使用從任意種子開始的最低模數MCRNG,直到您「循環」其週期,然後前進到下一個最大模數。

您會希望「模擬」模量以確保唯一性。例如,如果你的第一個ID是12位,所以你有一個模數M1 < = 2^12(但不是小得多),那麼你前進到16位,你想要選擇第二個模數M2 < = 2^16 - M1。所以第二層id是M1 + x_i,其中x_i是第二個r的第i個輸出。 32位的第三層將具有模數2^32-M2,其輸出將是M2 + y_i,其中y_i是其輸出等。

所需的唯一持久性存儲將是最後生成的ID和索引的序列中的MCRNG。

隨着時間的推移,有人可能會猜測這個算法沒有太多的麻煩。但一個臨時用戶不太可能這樣做。

1

假設你的計數器範圍是1到10000.切片[1,10000]到10個小單位,每個單位包含1000個數。這個小單位將跟蹤他們的最後一個ID。

unit-1 unit-2    unit-10 
[1 1000], [1001, 2000], ... ,[9000, 10000] 

當你需要一個ID時,只需從1-10單元中隨機選擇,並獲得該單元的最新ID。 e。g 首先,你的計數器是1,隨機選擇是單位-2,比你得到的ID = 1001; 第二次,你的計數器是2,隨機選擇是單位-1,比你會得到ID = 1; 第三次,你的計數器是3,隨機選擇單位是2,比你得到的ID = 1002; ...等等。