Generating unique codes in PHP/MySQL?

我是研究僧i 提交于 2019-11-30 02:05:02

If you need about 10 million unique keys (for example), the best approach is to pick a key-space that's exponentially bigger, and start randomly generating. Read about the Birthday Paradox -- it's the main thing you should be worried about. If you want 2^n unique and secure keys, make sure there are at least 2^(2 * n) possible values. Here's a rough O(n log n) algorithm:

  • Use a key space of at least 2^50 (so, in other words, allow 2^50 possible unique values), and you'll have barely any collisions in your entire dataset -- and anyone brute forcing your keys will have about even odds of getting a key if they try 2^25 of them.
  • generate as many random numbers as you need
  • index the database on your key (this is the O(n lg n) step: the sort)
  • page through the DB and iterate over the entire data set to trim duplicates (pseudocode below)
  • Delete the duplicate rows, and you're done.

Pseudocode:

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

Let's suppose you can use a character set of, say, 40 symbols of unambiguous upper,lower and numeric characters.

For a sequence of n chars, you've got 40n combinations

  • 404 = 2,560,000
  • 405 = 102,400,000
  • 406 = 4,096,000,000
  • 407 = 163,840,000,000
  • 408 = 6,553,600,000,000

Thus 8 chars gives a pretty good space to work in - if you generated 10 million codes, you'd have to try hundreds of thousands of combinations to brute force a code.

Or you come at from the other direction - give the number of possible codes, how many codes should you generate to avoid the trap they call the Birthday Paradox?

Taking the 8 char code, 6,553,600,000,000 is approx 242, thus you might reasonably generate 221 codes from it, or 2,097,152

Use a one time password algorithm?

RFC4225 details one based on HMAC algorithm.

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

but instead of using 0-9 digits base10 encoding, use base32.

Whatver method you use, I would suggest you add a check digit or two as a "first-line" defence against people mis-entering or trying to invent a number.

Oddly enough, with the following seed I was only able to generate 32 unique strings.

ABCDEFGHJKLMNPQRSTUVWXYZ23456789

With a longer seed I was able to generate many more--generated 40,000 unique strings successfully.

ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!