【问题标题】:Generating nice looking BETA keys生成漂亮的 BETA 密钥
【发布时间】:2012-04-29 00:39:37
【问题描述】:

我构建了一个即将启动 beta 测试的 Web 应用程序。我真的很想分发看起来不错的测试版邀请和密钥。

即A3E6-7C24-9876-235B

这是大约 16 个字符的十六进制数字。 它看起来像您可能会看到的典型 beta 密钥。 我的问题是生成这样的东西的标准方法是什么,并确保它是唯一的,并且某人猜出 beta 密钥并生成自己的密钥并不容易。

我有一些想法可能适用于 beta 密钥:

  • MD5 足够安全,但它又长又丑,可能会导致 0 和 O 或 1 和 l 混淆。
  • 我可以从一个长度为 16 位的大十六进制数开始。为了防止人们猜测下一个 beta 密钥可能每次都会将值增加一个随机数。即使我跳过大量数字,1111-1111-1111-1111 和 eeee-eeee-eeee-eeee 之间的数字范围也会有足够的空间。

我想我只是想知道是否有一种我在谷歌找不到的标准方法。有没有更好的办法?

【问题讨论】:

  • 如何将它们从加密 PRNG 中提取出来并将它们存储在一个大数据库中?
  • 使用具有小块大小的块密码(例如 Triple-des)加密数字 1 到 n 可能是一种替代方法。优点是不需要大型数据库。

标签: algorithm math encryption random beta


【解决方案1】:

规范的“唯一标识号”是uuid。有多种形式 - 例如,您可以从随机数(版本 4)或某个值的哈希(用户的电子邮件 + salt?)(版本 3 和 5)生成一种。

存在 java、python 等库。

PS 我必须补充一点,当我阅读您的问题标题时,我以为您正在寻找一些很酷和不同的东西。您可能会考虑使用“有趣”的单词列表并将单词与连字符组合以对数字进行编码(基于电子邮件 + salt 的哈希值)。恕我直言,这将更具吸引力:“您的 beta 代码是 secret-wombat-cookie-ninja”(我确定我读过一篇描述示例的文章,但现在找不到了)。

【讨论】:

  • 啊哈这是标准,谢谢。我一直在考虑做一些更酷的东西的想法,但你在互联网上的鼓励促成了这笔交易。制作“官方”外观的 beta 密钥可能会令人讨厌。这部漫画就是你所说的一个很好的例子:xkcd.com/936
  • 是的;我不确定您是否想在邀请中分发看起来像许可证密钥的东西......无论如何,祝你好运......
【解决方案2】:

一种方式(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 = "ABCDEF0123456789";

    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 random 类生成随机字节(可能修改字母长度)。

【讨论】:

  • 太棒了!唯一的问题是它不能确保生成的每个密钥都是唯一的。(与计数的解决方案相反)我需要不断检查我的数据库是否存在重复项。 (尽管这极不可能为我生成的密钥数量生成重复的 beta 密钥
  • 字母长度 = 16,字符串中的 16 个字符 = 16 ^16 个排列。比2000大一点!如果你能在接下来的一百万年里生成两个相同的,那是因为不恰当地使用了随机类。
  • @TylerJ.Hutchison 检查数据库是否存在应该是一个快速的操作,你甚至可以设置一个唯一的约束来防止意外地重复。
【解决方案3】:

计算能力很便宜,采用您对 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', ...

【讨论】:

    猜你喜欢
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 2016-12-31
    • 2014-02-01
    相关资源
    最近更新 更多