Генерация уникального ID

 
0
 
PHP
ava
taral | 21.03.2013, 00:31
На сайте постоянно создаются заказы. На каждый заказ необходимо сгенерировать уникальный id. Он должен быть достаточно простым для восприятия человеком и обязательно не должен повторятся.
Нельзя использовать id  с базы данных и как либо на него ориентироваться.
Пока придумал подвязаться на time() и частично перевести его в цифры. Для лучшей читаемости.
Примерно так

        $intval=time();
        $result='';

        for($i=0;$i<4;$i++) {
            $last=$intval%$count;
            $intval=($intval-$last)/$count;
            $result.=$letters[$last];
        }

        echo $result.$intval;

в результате получаю примерно такой код WKI0-811
в конец добавляю rand(10,99) для исключения дубляжей в ту же секунду. Получаю такое WKI0-811-45
Длинна и сложность кода устраивает. Не нравится 1. Возможность дубляжей хоть и очень небольшая. 2. Окончание 811 очень редко изменяется. Поскольку это грубо говоря года из time().
Также я уверен что есть более красивые решения. Спасибо за внимание
Comments (18)
ava
Nett | 21.03.2013, 00:28 (Edited 21.03.2013 01:34) #
Всё очень просто, http://php.net/manual/en/function.uniqid.php

uniqid()


Или


rand ( int $min , int $max )


Если надо что-то сильно уникальное попробуйте склеивать результат


$unique = rand (10000, 99999).'-'.rand (10000, 99999).'-'.rand (10000, 99999);
ava
Арантир | 21.03.2013, 01:18 #
Можно просто перевести unix-timestamp в 26-ичную систему счисления с буквами английского алфавита в качестве символов.

Время написания данной строки тогда будет выглядеть так: "EKULRDV"
Повторения в пределах секунды исключены. Можно добавить миллисекунды в конец: "EKULRDV903". Теперь повторения почти невозможны физически.

О переводе чисел в K-ичную систему можно почитать где угодно.
К счастью, у меня завалялся пример:

function decimalToKPos($d_number, &$k_number, $dictionary)
{
    $k = count($dictionary);
    $remainder = 0;
    $n = strlen($d_number);
    while ($d_number > 0) {
        $k_number[$n--] = $dictionary[$d_number % $k];
        $d_number = intval($d_number / $k);
    }
}
decimalToKPos(1363821311, $hex, ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']);
echo implode('', array_reverse($hex));
ava
baldina | 21.03.2013, 09:40 #
Цитата (taral @  20.3.2013,  23:31 findReferencedText)
не должен повторятся

чем плоха просто последовательная нумерация в связке с датой? (вспомните обычные бумажные счета, идентифицируемые датой и номером)
ava
skyboy | 21.03.2013, 09:53 #
Цитата (baldina @  21.3.2013,  08:40 findReferencedText)
чем плоха просто последовательная нумерация в связке с датой?

поддерживаю.
а не то придется выслушивать по телефону объяснения в стиле "«С» как доллар"
ava
taral | 21.03.2013, 11:32 #
Большое спасибо за ответы.
Скорее всего буду использовать ваш пример Arantir
baldina я согласен с тем что удобнее сообщать цифры. Но мне поставлены жесткие требования. И с этим ничего не поделать =)
ava
baldina | 21.03.2013, 11:44 #
закодируйте дату буквами (ДМГ), номер цифрами
день 1-26 - WA-WZ,  27-31 YA-YE
месяц 1-12 - A-L
год 2010-2036 A-Z

счет номер 45 от 21.03.2013 будет WUCD-045
ava
skyboy | 21.03.2013, 12:24 #
в свете собственных слов про трудность передачи по телефону, особенно людьми, у которых английский последний раз был в школе, советую отобрать буквы, которые легко читаются/понимаются и которые сложно перепутать(из пары "M-N" или "E-I" взять только одну)
ava
Fortop | 21.03.2013, 13:03 #
skyboy, но даты и цифры читаются вполне нормально учениками старше 3го класса smile
В общем автор юлит в чем-то.
ava
taral | 21.03.2013, 14:54 #
Цитата (Fortop @ 21.3.2013,  13:03)
skyboy, но даты и цифры читаются вполне нормально учениками старше 3го класса smile

В общем автор юлит в чем-то.

Нет. Просто на сайте используется база данных mongo. Где id 513bb26adffa82cf0a000042. А нужно выводить клиенту id заказа в нормальном виде. Причем заказов может быть очень много. По крайней мере заказчик настаивает на 100% уникальность. По этой причине если взять просто time() . rand(0,999) будет очень много цифр. Получить int по количеству заказов тоже не вариант потому что они могут удалятся. По причине большого кол. цифр выбрали заменить часть их на буквы. Тем более что заказчику нравится когда вначале буквы и дальше цифры. И смысла его переубеждать в этом нет =)
ava
Fortop | 21.03.2013, 16:39 #
Цитата (taral @  21.3.2013,  14:54 findReferencedText)
Получить int по количеству заказов тоже не вариант потому что они могут удалятся

В чем прикол?
ava
Gold Dragon | 21.03.2013, 16:58 #
а может проще использовать во этот формат?

$id = date("ymd-B");
ava
baldina | 21.03.2013, 17:34 #
идея неплохая, но будут повторы
подошло бы наверно что-то вроде date_format('Symd-siH-u');
ava
Gold Dragon | 21.03.2013, 18:48 #
Цитата (baldina @  21.3.2013,  18:34 findReferencedText)
идея неплохая, но будут повторы
это при каких условиях?
ava
baldina | 21.03.2013, 19:22 #
при условии генерации более одного id в день
http://liveworkspace.org/code/4jkooo$1
ava
Gold Dragon | 21.03.2013, 20:03 #
а вообще, задача изначально глупая.. Зачем что-о выдумывать когда есть порядковый номер. Ну если нет возможности использовать ID, ну так сделай отдельное поле.. и при следующем заказе делай запрос MAX(`field`), прибавляй единицу и радуйся. Не нравятся цифры. ну так замени буквами...
ava
taral | 21.03.2013, 21:24 #
Цитата (baldina @ 21.3.2013,  19:22)
при условии генерации более одного id в день

http://liveworkspace.org/code/4jkooo$1



added later:

Цитата (taral @  21.3.2013,  14:54 \\"findReferencedText\\")
заказов может быть очень много


365 в год мне кажется не очень большим числом заказов smile

Когда я говорил про большое число заказов это возможность возникновения нескольких заказов в секунду.
ava
baldina | 21.03.2013, 22:28 #
Цитата (taral @  21.3.2013,  21:24 findReferencedText)
Когда я говорил про большое число заказов это возможность возникновения нескольких заказов в секунду. 

именно поэтому я и сказал Gold Dragon, что будут повторы, и показал пример без этого недостатка
ava
Gold Dragon | 22.03.2013, 06:19 #
поэтому я и сказал что нет лучше ID чем простой порядковый номер  :-D

added later:
PS

Цитата (taral @  21.3.2013,  22:24 findReferencedText)
Когда я говорил про большое число заказов это возможность возникновения нескольких заказов в секунду. 
Это круто, но не верится... Просто если такой оборот у "магазина", то как-то "слабенькая" реализация...  smile 
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit