Вот мое решение.
Три части xyz, где x - это отметка времени, y - случайный код, а z - контрольная цифра, полученная путем объединения x и y.Но чтобы упростить (сделать его меньше), x и y задаются в пользовательской базе вместо числовой базы 10, а z по-прежнему задается в базе 10.
Примеры идентификаторов, которые вы можете получить с помощью этого подхода:
- LP9NTX-8D41-QW6R-9
- LP9NTY-5H3L-BFS7-5
- LP9NTZ-RWL3-D619-8
- LP9NVB-BW74-788W-6
- LP9NVW-G17D-4911-8
Таким образом, вы можете сортировать по отметке времени (обратите внимание, как это происходит в «возрастающем алфавитно-цифровом» порядке, если вы нене знаю точно, что такое числовая основа).
Для этого я использовал цифры + заглавные буквы base58 (в конце концов, не имеет значения, использовал ли я строчные или прописные), который является base62 без некоторых запутанных символов. Flickr, bit.ly и другие используют base58 для создания «дружественных» ссылок в Твиттере и т. П. .
Ниже приведен Verhoeff :: calcsum Проверка Диэгера группы D5 Верхоффа Dahnielson. Единственное редактирование, которое я сделал, заключалось в том, чтобы поместить его код в класс, так что он точно такой же.
Вот некоторый код: (* несколько изменен по сравнению с тем, что я обещал в строках там ^)
<?php
$time_divisor = 3;
$base = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ";//consider using another base **see note below**
$lower_limit = 50000;//just to avoiding to confuse the user with a lower number
$upper_limit = 1291467968;//1291467968 == ZZZZZZ in this base I used
//you can check the limit with base_decode("ZZZZZZ", $base);
$ptime = (int)($_SERVER['REQUEST_TIME']/$time_divisor);//or time();
$rand1 = mt_rand($lower_limit, $upper_limi);
$rand2 = mt_rand($lower_limit, $upper_limi);
$ptime_b = base_encode($time, $base);
$rand1_b = base_encode($rand1, $base);
$rand2_b = base_encode($rand2, $base);
$order_id = $ptime_b.$rand1_b.$rand2_b.Verhoeff::calcsum($time.$rand1.$rand2);
echo $order_id;
?>
Сразу после того, как я закончил писать это, мне в голову пришла другая, возможно, какая-то проблема.Я вспомнил, что вы не хотите, чтобы ваши потребители чувствовали себя оскорбленными.Таким образом, даже если плохие слова, такие как «f? Ck» или «4ss», в конечном итоге появятся, может быть, в порядке (и они почти наверняка будут), явные слова (как при изменении «4» для «a» в предыдущем слове) определенно,Из-за этого я рекомендую вам использовать вместо этого следующий альтернативный base / upper_limit:
<?php
$lower_limit = 27000;//=2111
$upper_limit = 809999;//=ZZZZ
$base = "123456789BCDFGHJKLMNPQRSTVWXYZ";//erased -a -e -u
?>
Обратите внимание, что если вы попытаетесь использовать большее число, вы достигнете верхнего предела PHP, а также лимита mt_rand,что можно увидеть с помощью mt_getrandmax ().Кроме того, я хотел бы сказать, что для того, что я вижу, энтропии mt_rand достаточно.
Если вам нужны большие числа для случайной части, я рекомендую просто добавить третью часть к этому с чем-то вроде mt_rand (i, j);где i и j - минимальные и максимальные значения для вашей базы, которые увеличат ваш идентификатор заказа на длину $ num-chars (на самом деле я сделал это, с указанной выше конфигурацией).
А на стороне БД этоуникальное поле, чтобы избежать столкновений.
Спасибо всем.