2008-12-10 59 views
6

Hrm ...這裏是我的CS知識讓我失望的地方。我想編寫一個算法來生成一個唯一的參考號。生成唯一的參考號碼策略

我不想使用連續數字,因爲它們引入了安全風險,我想使用 字母數字。裁判也有一個最小和最大長度。 (我不能使用一個GUID它太長)

理想情況下,我不想查詢我的持久層,以查看是否之前使用過ref。

我可以採用哪些策略?

+0

爲什麼序列號會成爲安全風險? – Juliet 2008-12-10 17:26:57

+0

因爲你可以猜測下一個數字是什麼。想象一下,如果您的銀行按順序分配了帳號......您可以輕鬆找到一系列帳號。 – JoshBerke 2008-12-10 17:38:50

回答

2

如果您擔心安全風險,那麼您需要一個密碼安全的隨機數生成器。你應該能夠告訴它你想要多少字節(即數字可以多長)。

2

如果這個數字將永遠是被人引用,我鼓勵你遵循這些準則在您的解決方案:

What is the best format for a customer number, order number?

如果你不能與數據庫synchorize,看看下一個數將是,並且您不能使用GUID或一個相對較長的隨機字符串,那麼您需要在ID中包含某種本地值。

例如,如果所有的客戶端都在一個已知的網絡上,則可以結束每個客戶端的IP地址D塊中的每個號碼。

或者,如果客戶端必須登錄並且每個用戶一次只能登錄一次,則可以在其中的某個編號中包含其用戶標識。

-1

將GUID截斷爲所需的大小。

如果你正在生成數字,除非它們是隨機的和巨大的,否則你最好檢查它們是否被使用過。

1

我在黑暗中刺穿了這裏,但是......你想要一個隨機值,它將是唯一的,但少於16個字節。你最好的選擇仍然是一個只有16字節的GUID ....你想使用字母數字......所以有些選項。

使用一個GUID,但對其進行編碼base64看起來像7QDBkvCA1 + B9K/U0vrQx1A這是22個字節,它仍然是一個本地GUID ...但比典型的字符串表示更短。

見文本編碼這裏:http://en.wikipedia.org/wiki/Globally_Unique_Identifier

另一種選擇是散列的GUID,但是你將失去一些獨特性,該怎麼在這裏是你的容忍水平非唯一的項目嗎?

==========

假設你有一個單一的過程中插入你可以emlpoyee一個高住低訓algorithim並相信你不必每次都打DB表。你只是在內存中存儲最後一個高值...當進程啓動時,你會去分貝找出你離開的地方:What's the Hi/Lo algorithm?

我還是說Guid是你最好的選擇... .16字節並不差,並且會與您想出的大多數字母數字解決方案一樣小。

0

一種方法可能是基於較小的數字子集生成數字。例如,您可以使用二進制序列根據godel編號生成。例如,在5z,3y,2x上將000映射到111會得到0,2,3,6,5,10,15,30。

當然,這太簡單了。但通過迭代「鹽」數字來生成參考數字,您根本不必跟蹤參考數字。當然,如果你有理由相信你不需要考慮碰撞事故。

0

如果可能在您的應用程序/環境中,您是否考慮添加時間作爲僞隨機生成數字的一部分?

即microtime中()+蘭特(10000,99999)

0

我一直在生產系統中成功這樣做:

  • 以當前時間(UTC,與微秒級精度)
  • 你的進程ID,線程ID
  • 您的計算機名稱
  • 鹽值(基本上是一個獨特的程序字符串)
  • 一個隨機值(最好是加密級PRNG)

將它放在內存中,可以是字符串,也可以是XOR值或其他類似值。 然後:

  • 用例如SHA-1
  • 對生成的數字執行模N將輸出縮小爲N個字節
  • 轉換爲十六進制或可打印的內容(如果需要)。

請注意,將UID縮小到N個字節會增加發生UID衝突的機會。

第一個列表中的所有輸入數據都是爲了確保您獲得散列的唯一基礎,前提是您擁有多臺計算機的集羣。你可以省略其中的一些,但是你必須確定它包含的東西會使你生成UID的每臺計算機都有所不同。