在PHP / MySQL中生成唯一代码?

时间:2008-10-20 18:55:07

标签: php mysql random generator serial-number

我正在与一个需要生成数百万字母数字代码的客户合作,这些代码用于杂志刮刮卡,瓶装奖品等。它们必须足够短以便在帽子上打印,他们希望确保不包括像1和I,0和O等模糊字符,并且必须明确存储它们以备将来使用 - 我们可以'只有一个算法可以在某人试图兑换一个时确定“有效性”。最后,他们希望确保代码随机分布在一个大的“代码空间”内,以便人们不能通过遍历字母表来猜测其他代码。

是否有任何针对生成这些代码集的合理有效算法的指针?我在信封的背面刮了几下,但是这个问题闻起来像是一个不知情的陷阱。

5 个答案:

答案 0 :(得分:13)

如果您需要大约1000万个唯一密钥(例如),最好的方法是选择一个指数级更大的密钥空间,并开始随机生成。阅读Birthday Paradox - 这是你应该担心的主要问题。如果您想要2 ^ n个唯一且安全的密钥,请确保至少有2 ^(2 * n)个可能的值。这是一个粗略的O(n log n)算法:

  • 使用至少2 ^ 50的密钥空间(因此,换句话说,允许2 ^ 50个可能的唯一值),并且您的整个数据集中几乎不会发生任何冲突 - 任何暴力强迫密钥的人都会如果他们尝试了2 ^ 25,那么获得钥匙的几率甚至可能。
  • 根据需要生成任意数量的随机数
  • 索引密钥上的数据库(这是O(n lg n)步骤:排序)
  • 页面通过数据库并迭代整个数据集以修剪重复项(下面的伪代码)
  • 删除重复的行,然后就完成了。

伪代码:

$last = null;
while ($current = getnext()) {
    if ($last == $current) {
        push($toDelete, $current);
    }
    $last = $current;
}

答案 1 :(得分:7)

假设您可以使用40个明确的上,下和数字符号的字符集。

对于一系列n个字符,你有40个 n 组合

  • 40 4 = 2,560,000
  • 40 5 = 102,400,000
  • 40 6 = 4,096,000,000
  • 40 7 = 163,840,000,000
  • 40 8 = 6,553,600,000,000

因此,8个字符提供了相当好的工作空间 - 如果您生成了1000万个代码,则必须尝试数十万个组合来强制执行代码。

或者你是从另一个方向来的 - 给出可能的代码的数量,你生成的应该的代码数量,以避免他们称之为{{3}的陷阱}?

取8个字符代码,6,553,600,000,000约为2 42 ,因此您可以合理地从中生成2个 21 代码,或者2,097,152

答案 2 :(得分:0)

使用一次性密码算法?

RFC4225详细介绍了一种基于HMAC算法的方法。

http://www.ietf.org/rfc/rfc4226.txt

但不是使用0-9位base10编码,而是使用base32。

答案 3 :(得分:0)

你使用哪种方法,我建议你添加一两个校验位作为“第一线”防范,以防止人们误入歧途或试图发明一个数字。

答案 4 :(得分:-3)

奇怪的是,使用下面的种子,我只能生成32个唯一的字符串。

ABCDEFGHJKLMNPQRSTUVWXYZ23456789

使用更长的种子,我能够生成更多 - 成功生成40,000个唯一字符串。

ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789