2012-04-29 50 views
3

我構建了一個即將推出beta測試的web應用程序。我真的很想交出測試版邀請和鑰匙,看起來不錯。生成漂亮的BETA鍵

即A3E6-7C24-9876-235B

這是大約16字符,十六進制數字。 它看起來像你可能看到的典型的beta鍵。 我的問題是什麼是一種標準的方式來產生這樣的事情,並確保它是唯一的,並且它不會容易有人猜測測試密鑰並生成它們自己的。

我有一些想法,應該會很適合測試鍵的作用:

  • MD5是這個足夠安全,但它是漫長的,難看的,並可能導致0和O,或1和L之間的混淆。
  • 我可以從16位長的十六進制數字開始。爲了防止人們猜測下一次測試版密鑰可能每次增加一個隨機數的值。即使我跳過大量數字,1111-1111-1111-1111和eeee-eeee-eeee-eeee之間的數字範圍也有充足的餘地。

我想我只是想知道是否有一個標準的方式來做到這一點,我沒有找到谷歌。有沒有更好的辦法?

+1

如何只拉出一個加密PRNG的並將它們存儲在一個數據庫中大? – CodesInChaos 2012-04-29 00:49:53

+0

使用小塊大小的塊密碼(如triple-des)加密數字1到n可能是另一種選擇。具有您不需要大型數據庫的優點。 – CodesInChaos 2012-04-29 00:52:40

回答

3

規範的「唯一標識號碼」是uuid。有各種形式 - 例如,您可以從隨機數(版本4)或某個值的哈希(用戶的電子郵件+鹽?)(版本3和5)生成一個。

存在java,python和更多的庫。

PS我必須補充一點,當我閱讀你的問題標題時,我以爲你正在尋找一些很酷和不同的東西。您可以考慮使用「有趣」的單詞列表,並將單詞與連字符組合以編碼一個數字(基於電子郵件+鹽的散列)。這將是更有吸引力的imho:「你的測試代碼是secret-wombat-cookie-ninja」(我確信我閱讀了一篇描述示例的文章,但現在我找不到它)。

+0

啊哈這就是標準,謝謝。我一直在想辦法讓事情變得更酷,但你的互聯網鼓勵讓交易成爲可能。製作'官方'看beta鍵可能會惹人注目。這個漫畫是你談論的很好的例子:http://xkcd.com/936/ – 2012-04-29 03:39:42

+0

是的;我不確定你想在邀請中發放一些看起來像許可證密鑰的東西......無論哪種方式,祝你好運! – 2012-04-29 03:47:59

3

的一種方式(C#但是代碼移植到其他語言很簡單):

private static readonly Random random = new Random(Guid.NewGuid().GetHashCode()); 

static void Main(string[] args) 
{ 
    string x = GenerateBetaString(); 
} 

public static string GenerateBetaString() 
{ 
    const string alphabet = "ABCDEF"; 

    string x = GenerateRandomString(16, alphabet); 

    return x.Substring(0, 4) + "-" + x.Substring(4, 4) + "-" 
     + x.Substring(8, 4) + "-" + x.Substring(12, 4); 
} 

public static string GenerateRandomString(int length, string alphabet) 
{ 
    int maxlen = alphabet.Length; 
    StringBuilder randomChars = new StringBuilder(length); 

    for (int i = 0; i < length; i++) 
    { 
     randomChars.Append(alphabet[random.Next(0, maxlen)]); 
    } 

    return randomChars.ToString(); 
} 

輸出:

97A8-55E5-C6B8-959E 
8C60-6597-B71D-5CAF 
8E1B-B625-68ED-107B 
A6B5-1D2E-8D77-EB99 
5595-E8DC-3A47-0605 

這樣做的方式讓你在字母表中的字符的精確控制。如果你需要加密強度隨機性(不太可能)使用cryto隨機類生成隨機字節(可能修改字母表長度)。

+0

太棒了!唯一的問題是,它不能確保生成的每個密鑰都是唯一的(與解決方案相反),我需要不斷檢查我的數據庫以找到可能的重複項。 (雖然這很可能不會產生重複的β鍵,但是我產生的鍵的數量<2000) – 2012-04-29 03:51:22

+0

字母長度= 16,16個字符串= 16^16排列。比2000年大了很多!如果在未來的幾百萬年內可以生成兩個相同的文件,那是因爲不恰當地使用了隨機類。 – 2012-04-29 04:08:19

+0

@ TylerJ.Hutchison檢查數據庫是否存在應該是一個快速操作,你甚至可以設置一個唯一的約束來防止意外重複。 – jbtule 2012-05-01 23:00:17

1

計算能力很便宜,把你對MD5的想法與你自己設計的「審美」結合起來。下面的代碼幾乎可以瞬間生成2000個唯一鍵,但其中沒有0,1,L,O字符。修改aesthetic,以適應任何附加條件:

import random, hashlib 

def potential_key(): 
    x = random.random() 
    m = hashlib.md5() 
    m.update(str(x)) 
    s = m.hexdigest().upper()[:16] 
    return "%s-%s-%s-%s" % (s[:4],s[4:8],s[8:12],s[12:]) 

def aesthetic(s): 
    bad_chars = ["0","1","L","O"] 
    for b in bad_chars: 
     if b in s: return False 
    return True 

key_set = set() 

while len(key_set) < 2000: 
    k = potential_key() 
    if aesthetic(k): 
     key_set.add(k) 

print key_set 

例鍵:

'4297-CAC6-9DA8-625A', '43DD-2ED4-E4F8-3E8D', '4A8D-D5EF-C7A3-E4D5', 
'A68D-9986-4489-B66C', '9B23-6259-9832-9639', '2C36-FE65-EDDB-2CF7', 
'BFB6-7769-4993-CD86', 'B4F4-E278-D672-3D2C', 'EEC4-3357-2EAB-96F5', 
'6B69-C6DA-99C3-7B67', '9ED7-FED5-3CC6-D4C6', 'D3AA-AF48-6379-92EF', ...