Blog. Just Blog

Генерация последовательности уникальных кодов на PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Иногда возникает задача генерации последовательности уникальных кодов по определенному формату. Это могут быть какие-нибудь одноразовые токены, коды лотерейных билетов, серийные номера, scratch-карты, да мало ли чего. Простое использование ГСЧ в этом случае не дает 100% гарантии, так как выдаваемые им значения могут повторяться, а при большом количестве кодов количество повторений будет только расти. Предлагаю вам следующее решение:
  1. // Набор символов для генерации кодов
  2. $str='1234567890ABCDEF';
  3. // Длина кода без учета разделителей
  4. $code_length=16;
  5. // Нужное количество кодов
  6. $codes_count=300000;
  7. // Позиции разделителя (0 - не надо)
  8. $code_separartor=4;
  9.  
  10. $tmp=array();
  11. $str_length=strlen($str)-1;
  12.  
  13. // Цикл до заполнения массива
  14. while (count($tmp)<$codes_count) {
  15.     // Сгенерировать индекс массива
  16.     $code='';
  17.     for ($i=0$i<$code_length$i++){
  18.         // Разделитель можно не добавлять
  19.         if ($i>&& $code_separartor>&& $i%$code_separartor==0) { $code.='-';}
  20.         $code.=substr($strmt_rand(0,$str_length), 1);
  21.     }
  22.     // Или в массив добавится новый элемент, или
  23.     // перепишется поверх уже имеющийся
  24.     $tmp[$code]=1;
  25. }
  26. // Теперь в массиве $codes уникальные коды
  27. $codes=array_keys($tmp);
Коды генерируются гарантированно уникальные (в пределах одной сессии). Это достигается за счет того, что в качестве кода сперва используются ключи массива, а не значения. Даже если какой-либо код будет сгенерирован повторно, то просто перезапишется уже имеющийся элемент массива, а не добавится новый. Отсутствие проверок типа in_array значительно повышает скорость работы генератора. Главный недостаток этого алгоритма в том, что для генерации больших объемов данных потребуется много оперативной памяти. Для особо критичных случаев при выборе символов, составляющих код, лучше использовать не программный ГСЧ, а какой-нибудь аппаратный, чтобы обеспечить максимальную непредсказуемость данных.

Для красоты символы в готовых кодах можно разделить на группы, используя разделитель. Ниже приведены несколько примеров кодов с разделителями и без. Разделитель на 8-й позиции:

[0] => A6DC5536-81EFDE02
[1] => 525586D3-8773E542
[2] => A21B0A2E-8CC3240B
[3] => 3F66FCBC-E6B9A8AF
[4] => 8EFEBB51-B3CA57AE
[5] => F888C622-D14A0AD6
[6] => FFDE76BA-C218681A
[7] => 17E262B3-BFA110C8
[8] => B64A8B15-399EA874
[9] => 5CF57146-0C0A0022

Разделитель на каждой 4-й позиции:

[0] => 0C06-85BC-7201-E7B6
[1] => D4F7-E0A3-384F-9938
[2] => 2350-2DC4-E85C-70DC
[3] => 1EF3-7998-AE3E-A4E3
[4] => 144C-B738-C683-38A5
[5] => 1248-AB10-0881-86B6
[6] => 2528-8C13-1C04-C23F
[7] => A6EB-79B6-57A9-3B4F
[8] => 4B8B-9ED0-A737-FA1B
[9] => AFFB-2DB8-85FF-9484

Только цифры, разделителей нет:

[0] => 5437151350716448
[1] => 2133900712368713
[2] => 4785741281845748
[3] => 5593174921255829
[4] => 3735223131404105
[5] => 4795261818633735
[6] => 6881470329618676
[7] => 0408149990357380
[8] => 6868536157610001
[9] => 3155755636830187

При тестировании для генерации 500 тысяч уникальных 16-значных кодов у меня было затрачено в среднем 2-3 секунды.

Поделиться ссылкой ВКонтакте
Просмотров: 11368 | Комментариев: 6

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Геннадий (10.09.2014 в 09:39):
Отличный код, спасибо.
lammer (13.10.2013 в 11:46):
Генерируем нужное количество значений (последовательно, с шагом, по алгоритму) и перемешиваем Fisher–Yates shuffle (a la тасовка колоды карт). http://en.wikipedia.org/wiki/K...odern_method
ManHunter (11.10.2013 в 15:16):
Для решения 99,99999% задач хватает программного ГПСЧ. Для остальных задач ГСЧ выпускаются в виде отдельной платы (насколько я знаю), а некоторые ГСЧ народ сам паяет.
Андрей (11.10.2013 в 15:05):
Странно что при всей сложности ПК нет штатного аппаратного ГСЧ. Или мои сведения устарели ?
ManHunter (11.10.2013 в 13:51):
"Аппаратный генератор случайных чисел - устройство, которое генерирует последовательности случайных чисел на основе измеряемых параметров протекающего физического процесса. Работа таких устройств часто основана на использовании надёжных источников энтропии, таких как тепловой шум, фотоэлектрический эффект, другие квантовые явления. Эти процессы, в теории, абсолютно непредсказуемы" (c) Wiki

Это если требуется генерить что-то в промышленных масштабах и очень-очень важное.
Grey (11.10.2013 в 13:49):
аппаратный в смысле датчиков темературы, напряжения и т.п.?

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.18 сек. / MySQL: 2 (0.0065 сек.) / Память: 4.5 Mb
Наверх