Создание уникальных кодов в PHP / MySQL?

Я работаю с клиентом, которому нужно генерировать миллионы буквенно-цифровых кодов, используемых в журнальных скрещенных карточках, призах на бутылочной бутылке и т. Д. Они должны быть достаточно короткими, чтобы печатать на кепке, они хотят удостовериться, что двусмысленные символы, такие как 1 и I, 0 и O и т. Д., Не включены, и они должны быть явно сохранены для использования в будущем – t просто имеет алгоритм, который определяет «действительность», когда кто-то пытается его выкупить. Наконец, они хотят убедиться, что коды случайным образом распределены внутри большого «кодового пространства», чтобы люди не могли просто угадать дополнительные коды, прогуливаясь по алфавиту.

Существуют ли какие-либо указания относительно разумно эффективных алгоритмов для генерации таких кодовых наборов? Я поцарапал несколько на обратной стороне конверта, но эта проблема пахнет ловушкой для неосторожного.

Если вам требуется около 10 миллионов уникальных ключей (например), лучшим подходом является выбор пространства ключа, которое экспоненциально больше и начнет произвольно генерировать. Читайте о Парадоксах дня рождения – это главное, о чем вам следует беспокоиться. Если вы хотите, чтобы 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; } 

Предположим, вы можете использовать набор символов, скажем, 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 символов дают довольно хорошее пространство для работы – если вы создали 10 миллионов кодов, вам придется попробовать сотни тысяч комбинаций для перебора кода.

Или вы приходите с другого направления – укажите количество возможных кодов, сколько кодов вы должны генерировать, чтобы избежать ловушки, которую они называют Парадоксальным днем ​​рождения ?

Принимая 8-значный код, 6 553 600 000 000 составляет около 2 42 , таким образом, вы можете разумно генерировать 2 21 код из него или 2,097,152

Использовать алгоритм одноразового пароля?

RFC4225 подробно описывает алгоритм HMAC.

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

но вместо того, чтобы использовать кодировку base10 0-9, используйте base32.

Какой бы метод вы ни использовали, я бы предложил вам добавить контрольную цифру или две в качестве защиты «первой линии» против людей, которые ошибочно вводили или пытались изобрести номер.

Как ни странно, со следующим семенем я смог генерировать только 32 уникальные строки.

ABCDEFGHJKLMNPQRSTUVWXYZ23456789

С более длинным семенем я смог сгенерировать еще много – сгенерированных 40000 уникальных строк.

ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789ABCDEFGHJKLMNPQRSTUVWXYZ234567892345678923456789