2016-06-14 77 views
0

我有一個users表,我需要爲每個用戶創建一個唯一的,隨機的字母數字「ID」(它們通常具有自動增量ID)。這個標識符必須:如何生成與給定模式匹配的隨機外觀唯一標識

  • 是唯一
  • 是隨機尋找
  • 匹配的模式AAAA-1234(4個字母,4個數字)

有沒有更好的辦法,而不是不斷隨機生成的字符串,直到我發現一個不在數據庫中的呢?

+0

當你說'隨機看'你的意思是這些數字不應該是相應的? –

+0

@PavelPetrov – nXu

+0

可能是您需要的算法類似於生成信用卡號碼的算法。如果你在Cryptography SE中提出這個問題,你可能會得到更好的答案。 –

回答

2

爲每個用戶指定一個無聊舊順序的整數(或使用您提到的其他ID)。稱它爲$x

Set $x = (($x + 2135587861) * 2654435769) & 0xffffffff

設置$x = $x^($x >> 15)

再次設置$x = (($x + 2135587861) * 2654435769) & 0xffffffff

計算$x % 26並根據結果選擇一個字母a-z。設置$x = $x/26。重複四次(我不知道PHP,所以你在這裏得到口頭指示)。

計算$x % 10並根據結果選擇數字0-9。設置$x = $x/10。重複四次。

頭六個結果我得到的是:

HSQG-2102 
DNQO-1176 
TEKJ-5435 
EHWX-6540 
UPPH-0450 
MVIX-5036 

這不完全完美,但它是不明顯的。也許這就夠了。

此外,它只適用於前40億(ish)用戶在碰撞之前,但這只是一點點的字符串格式的限制。

+0

我真的不明白這裏的數字,但如果我看到正確,這基本上意味着每個$ x將映射到恰好一個字符串,這將是唯一的,直到$ x <16^8,對吧? – nXu

+1

是的,它們是獨一無二的。所有的神奇數字都是任意的,我只是選擇了一些看起來可行的東西。我使用了黃金比例的前64位。唯一的限制是乘數必須是奇數 - 它具有數學特性,即使在&&0xffffffff之後,每個可能的輸入都映射到唯一的輸出。由於所有操作都具有相同的屬性,因此我們知道我們不會將任何兩個輸入摺疊到相同的輸出(碰撞)中,並且理論上我們可以反轉操作以發現原始數字。 – sh1

+0

謝謝你的解釋! – nXu