Насколько уникальным является uniqid?

Этот вопрос не является проблемой для решения проблемы, это скорее просто вопрос любопытства. Функция uniqid PHP имеет больше энтропийного флага, чтобы сделать вывод "более уникальным". Это заставило меня задаться вопросом, насколько вероятно, что эта функция будет производить один и тот же результат более одного раза, когда больше_вентропия истинна, а если нет. Другими словами, насколько уникальным является uniqid, когда активирована функция more_entropy, а не когда она отключена? Есть ли недостатки в том, что функция more_entropy включена все время?

Ответы

Ответ 1

Обновление, март 2014:

Во-первых, важно отметить, что uniqid является немного неправильным, поскольку он не гарантирует уникальный идентификатор.

В Документация по PHP:

Внимание!

Эта функция не создает случайную или непредсказуемую строку. Эта функция не должна использоваться в целях безопасности. Использовать криптографически защищенная случайная функция/генератор и криптографически безопасный хэш функции для создания непредсказуемого безопасного идентификатора.

и

Эта функция не генерирует криптографически защищенные токены, в факт без каких-либо дополнительных параметров, возвращаемое значение немного отличается от microtime(). Если вам нужно сгенерировать криптографически безопасные токены используют openssl_random_pseudo_bytes().


Установка большей энтропии в true порождает более уникальное значение, однако время выполнения больше (хотя и в малой степени), согласно документам:

Если установлено значение TRUE, uniqid() добавит дополнительную энтропию (используя объединенный линейный конгруэнтный генератор) в конце возврата значение, что увеличивает вероятность того, что результат будет уникальным.

Обратите внимание на строку increases the likelihood that the result will be unique, и это не гарантирует уникальность.

Вы можете "бесконечно" стремиться к уникальности, вплоть до точки и улучшать с помощью любого количества процедур шифрования, добавляя соли и тому подобное - это зависит от цели.

Я бы рекомендовал посмотреть комментарии к основной теме PHP, в частности:

http://www.php.net/manual/en/function.uniqid.php#96898

http://www.php.net/manual/en/function.uniqid.php#96549

http://www.php.net/manual/en/function.uniqid.php#95001

Что я рекомендую, так это то, почему вам нужна уникальность, это для безопасности (например, для добавления в процедуру шифрования/скремблирования)? Кроме того, насколько он уникален? Наконец, посмотрите на скорость рассмотрения. Пригодность изменится с учетом основных соображений.

Ответ 2

Вещи уникальны, если вы убедитесь, что они уже не существуют. Неважно, какую функцию вы используете для создания "случайной" строки или идентификатора, если вы не дважды проверяете, что это не дубликат, тогда всегда есть такая возможность.;)

В то время как uniqid основан на текущем времени, все еще применяется предостерегающее примечание - это зависит только от того, где вы будете использовать эти "уникальные идентификаторы". Подсказка ко всему этому заключается в том, где говорится "более уникально". Уникальный уникальный. Как вы можете иметь что-то более или менее уникальное, немного запутывает меня!

Проверка, как указано выше, и объединение всего этого материала позволит вам получить что-то, приближающееся к уникальности, но все это относительно того, где будут использоваться ключи и контекст. Надеюсь, что это поможет!

Ответ 3

Из обсуждений о функции на сайте PHP:

Как и другие ниже, без префикса и без "добавленной энтропии" это функция просто возвращает UNIX временная метка с добавлением микросекунды счетчик как шестнадцатеричный номер; это больше или менее просто microtime(), в форме гексита.

[...]

Также стоит отметить, что поскольку microtime() работает только с системами, имеющими gettimeofday() > present, которые Windows изначально НЕ ДЕЛАЕТ, uniqid() может дать только временную метку UNIX с однократной разрешающей способностью в среде Windows.

Другими словами, без "more_entropy" функция абсолютно ужасна и никогда не должна использоваться, период. Подписывая документацию, флаг будет использовать "объединенный линейный конгруэнтный генератор" для "добавления энтропии". Ну, это довольно слабый RNG. Поэтому я полностью пропустил эту функцию и использовал что-то, основанное на mt_rand с хорошим семенем для вещей, которые не имеют безопасности, и SHA-256 для вещей, которые есть.

Ответ 4

Без флага more_unique он возвращает временную метку unix с микросекундным счетчиком, поэтому, если два вызова выполняются в одну и ту же микросекунду, тогда они вернут один и тот же "уникальный" идентификатор.

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

Ответ 5

Соответствующий бит из исходного кода -

if (more_entropy) {
    uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10);
} else {
    uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec);
}

Итак, more_entropy добавляет девять несколько случайных десятичных цифр (php_combined_lcg() возвращает значение в (0,1)) - это 29.9 бит энтропии, вершины (на самом деле, вероятно, меньше, поскольку LCG не является криптографически надежным генератором псевдослучайных чисел).