2015-03-24 2 views
0

Мне нужно сгенерировать уникальные идентификаторы транзакций. Система позволяет цифры, буквы, дефисы и подчеркивания, но не полные остановки.Сгенерировать читаемый случайный уникальный идентификатор

Функция Я в настоящее время использую,

generate_id() { 
    $id = uniqid('P_', true); 
    $id = str_replace('.', '-', $id); 
    return $id; 
} 

Пример вывода:

P_551171d3dd8a93-57457934

Однако недавно я обнаружил, что (а) uniqid() ISN (обязательно), и (б) моему клиенту время от времени требуется повторно указывать эти идентификаторы, сравнивать их, искать их и т. д. Текущие идентификаторы не являются v более читабельны и трудны для глазного яблока. (Я думал, что это были чисто для внутреннего использования в платежной API. Я только недавно понял, что клиент был на самом деле читать вещи.)

Так я думал об изменении этого,

function generate_id() { 
    $s = ''; 
    for ($i = 0; $i < 5; $i++) { 
     if ($s) { 
      $s .= '-'; 
     } 
     $s .= bin2hex(openssl_random_pseudo_bytes(2)); 
    } 
    return $s; 
} 

Пример вывода:

ced7-1cef-5331-193c-907d

openssl_random_pseudo_bytes() является рекомен ded способ генерации случайных уникальных идентификаторов, но я боюсь, что это четыре раза и конкатенирование (которое я делаю только потому, что это самый простой способ разделить его с дефисами для удобства чтения) может скомпрометировать его. Должен ли я генерировать одну длинную строку, а затем манипулировать ею, чтобы добавить дефис?

Или, действительно, должен ли я вообще что-то сделать? На самом деле я не возражаю против того, как выглядит идентификатор транзакции, пока он уникален и относительно легким для глазного яблока или повторного ввода.

+0

строго по математике он с Imposible случайный уникальный идентификатор, так как случайное косяк быть уникальным. Если вы хотите 100% уникальный идентификатор, вам нужно сделать поле автоматического приращения –

+0

Если клиент будет переименовывать эти уникальные идентификаторы, включите контрольную цифру (или, скорее, 2, например, mod97-10). Это wil void typo-id! – Nanne

+1

Расширение на Poignt @ Benjamin, err, point: существует два подхода к уникальным идентификаторам: централизованно управляется с помощью счетчика, который гарантирует уникальность; или децентрализованным с числом, достаточно длинным, с достаточным количеством (P) RNG, что столкновения * маловероятны *, чтобы иметь значение. Если вы используете децентрализованную случайную модель, вычислите свои вероятности. – deceze

ответ

2

Вызов openssl_random_pseudo_bytes много раз подряд не должен быть проблемой. Если вы читаете одну длинную строку случайных байтов или много коротких строк случайных байтов, это не имеет значения, они все еще случайны. Я бы еще изменить этот код на это, потому что это проще:

join('-', str_split(bin2hex(openssl_random_pseudo_bytes(40)), 4)) 

Это почти выглядит как UUID уже, так что вы можете на самом деле хотите использовать один из тех, кто вместо этого. В то время как случайные байты должны do, UUID явно предназначены для того, чтобы быть глобально уникальными с достаточно высокой вероятностью, что вам вообще не нужно об этом беспокоиться. Используйте http://pecl.php.net/package/uuid или вашу альтернативную предпочтительную реализацию.

0

Используйте UUID. Он может быть сформирован из uniqid() и пользовательского алгоритма или с использованием библиотеки. Если вы получаете столкновение с использованием UUID, < вставьте случайный массивный подарок здесь>.

https://github.com/ramsey/uuid

+1

* «он может быть образован из uniqid» * - wut? Как? – deceze

+0

Не напрямую, а через созданный алгоритм, поэтому использование библиотеки или пакета проще, как мы уже упоминали. – Spechal

+0

'uniqid', безусловно, ужасный PRNG для использования в качестве основы для UUIDs ... – deceze

Смежные вопросы