Какую версию UUID использовать?


332

Какую версию UUID вы должны использовать? Я видел множество потоков, объясняющих, что влечет за собой каждая версия, но у меня возникают проблемы с определением того, что лучше для каких приложений.


2
Каковы ваши выборы?
Гейб

Все, что работает с питоном. Так что я думаю, это docs.python.org/2/library/uuid.html . 1,3,4,5.
user1802143

Если вам интересно узнать о версиях 3 и 5, см. Этот вопрос, « Генерация UUID v5». Что такое имя и пространство имен? ,
Василий Бурк

Ответы:


414

Есть два разных способа генерации UUID.

Если вам просто нужен уникальный идентификатор, вам нужна версия 1 или версия 4.

  • Версия 1: генерируется уникальный идентификатор на основе MAC-адреса сетевой карты и таймера. Эти идентификаторы легко предсказать (учитывая один, я мог бы угадать другой) и их можно отследить до вашей сетевой карты. Создавать их не рекомендуется.

  • Версия 4: они генерируются из случайных (или псевдослучайных) чисел. Если вам просто нужно сгенерировать UUID, это, вероятно, то, что вы хотите.

Если вам нужно всегда генерировать один и тот же UUID из заданного имени, вам нужна версия 3 или версия 5.

  • Версия 3: генерируется уникальный идентификатор из хеша MD5 пространства имен и имени. Если вам нужна обратная совместимость (с другой системой, которая генерирует UUID из имен), используйте это.

  • Версия 5: Это генерирует уникальный идентификатор из хэша SHA-1 пространства имен и имени. Это предпочтительная версия.


17
Я бы добавил: если вам нужно сгенерировать reproducibleUUID из заданного имени, вам нужна версия 3 или версия 5. Если вы подадите этот алгоритм на тот же вход, он сгенерирует тот же результат.
anregen

3
В среде облачных вычислений (такой как AWS или GAE), казалось бы, слабость версии 1 превращается в забвение. Там, где с течением времени могут быть тысячи различных MAC-адресов, примененных к генератору UUID данного приложения, устраняя предсказуемость и / или отслеживаемость.
Буффало Рабор

3
@ user239558 Учитывая, что целью UUID является его уникальность, UUIDv5 все еще может быть предпочтительным.
Эпикурист

7
Этот комментарий о том, что Версия 1 «не рекомендуется», является чрезмерно упрощенным. Во многих ситуациях это действительно хорошо и предпочтительнее. Но если у вас есть проблемы с безопасностью, связанные с утечкой любого из этих элементов информации из UUID, которые могут быть предоставлены ненадежным субъектам: (a) MAC-адрес компьютера, создающего UUID, или (b) дату и время при создании, затем избегайте Версии 1. Если эти две части информации не являются конфиденциальными, то Версия 1 - отличный способ.
Василий Бурк

9
Что случилось с версией 2?
Мэтью Ву

53

Если вы хотите случайное число, используйте библиотеку случайных чисел. Если вам нужен уникальный идентификатор с эффективностью 0,00 ... здесь больше 0 ... 001% вероятности столкновения, вам следует использовать UUIDv1. Смотрите пост Ника для UUIDv3 и v5.

UUIDv1 НЕ безопасен. Это не должно быть. Он должен быть УНИКАЛЬНЫМ, не угаданным. UUIDv1 использует текущую временную метку, плюс идентификатор машины, а также некоторые случайные элементы, чтобы создать число, которое никогда не будет сгенерировано этим алгоритмом снова. Это подходит для идентификатора транзакции (даже если все делают миллионы транзакций / с).

Если честно, я не понимаю, почему существует UUIDv4 ... после прочтения RFC4122 похоже, что эта версия НЕ устраняет возможность коллизий. Это просто генератор случайных чисел. Если это так, то у вас есть очень хороший шанс, что две машины в мире в конечном итоге создадут один и тот же «UUID» v4 (цитаты, потому что нет механизма, гарантирующего U.niversal U.niqueness). В этой ситуации я не думаю, что алгоритм принадлежит RFC, описывающему методы для генерации уникальных значений. Это было бы в RFC о генерации случайности. Для набора случайных чисел:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)

67
Вы не увидите столкновения двух реализаций UUID версии 4, если не будете генерировать миллиард UUID каждую секунду в течение столетия и не выиграете бросок монеты . Помните, set_sizeэто 2 ^ 122, который очень большой .
Кевин

8
Алгоритм V4 не является последовательным, то есть существует вероятность того, что первые два UUID, сгенерированные v4, могут совпадать. То, что вариантов много, не означает, что вам нужно исчерпать уникальные опции, прежде чем вы создадите повтор. Это может произойти в любое время.
anregen

7
Вы не в состоянии сделать математику. Мы (как вид) не генерируем 1 миллиард UUID каждую секунду. Так что до первого столкновения у нас более 100 лет (в среднем).
Кевин

31
V4 "может" столкнуться, но вероятность исключительно низкая, что для большинства вариантов использования стоит риска. Re: «две машины в мире в конечном итоге создают один и тот же UUID'v4», конечно, но это не проблема, потому что большинство машин в мире, которые используют UUID, используют их в разных контекстах. Я имею в виду, что если я сгенерирую такой же UUID для своего внутреннего приложения, как и для своего внутреннего приложения, то это не имеет значения. Столкновения имеют значение только в том случае, если они происходят в одном и том же контексте. (помните, что даже внутри приложения многие UUID не обязательно должны быть уникальными во всем приложении, только в контексте, в котором они используются)

6
Похоже, если вам не нужен Guid для обеспечения безопасности, используйте версию 1. Если вам нужна безопасность и вам повезло (или вам не повезло), используйте версию 4.
Vaccano

16

Это очень общий вопрос. Один из ответов: «это зависит от того, какой тип UUID вы хотите сгенерировать». Но лучше то, что: «Ну, прежде чем я отвечу, вы можете сказать нам, почему вам нужно кодировать свой собственный алгоритм генерации UUID вместо вызова функциональности генерации UUID, которую предоставляют большинство современных операционных систем?»

Делать это проще и безопаснее, и, поскольку вам, вероятно, не нужно создавать свои собственные, зачем беспокоиться о кодировании реализации? В этом случае ответом будет использование того, что предоставляет ваш O / S, язык программирования или инфраструктура. Например, в Windows есть CoCreateGuid или UuidCreate или одна из различных оболочек, доступных из многочисленных используемых сред. В Linux есть uuid_generate .

Если вы, по какой - то причине абсолютно необходимо создать свой собственный, то , по крайней мере , есть смысл хорошо , чтобы держаться подальше от генерации v1 и v2 UUID , . Это сложно сделать это правильно. Вместо этого придерживайтесь UUID v3, v4 или v5.

Обновление : В комментариях, вы говорите , что вы используете Python и ссылку на это . Просматривая предоставленный интерфейс, проще всего будет сгенерировать UUID v4 (то есть созданный из случайных данных) с помощью вызова uuid.uuid4().

Если у вас есть данные, которые необходимо (или может) хэшировать для создания UUID, то вы можете использовать v3 (который зависит от MD5) или v5 (который основан на SHA1). Генерация UUID v3 или v5 проста: сначала выберите тип UUID, который вы хотите сгенерировать (вам, вероятно, следует выбрать v5), а затем выберите соответствующее пространство имен и вызовите функцию с данными, из которых вы хотите использовать для генерации UUID. Например, если вы хэшируете URL, вы должны использовать NAMESPACE_URL:

uuid.uuid3(uuid.NAMESPACE_URL, 'https://ripple.com')

Обратите внимание, что этот UUID будет отличаться от UUID v5 для того же URL-адреса, который создается следующим образом:

uuid.uuid5(uuid.NAMESPACE_URL, 'https://ripple.com')

Хорошим свойством URL v3 и v5 является то, что они должны быть совместимы между реализациями. Другими словами, если две разные системы используют реализацию, которая соответствует RFC4122, они будут (или, по крайней мере, должны ) генерировать один и тот же UUID, если все другие вещи равны (то есть генерируют один и тот же UUID версии, с тем же пространством имен и те же данные). Это свойство может быть очень полезно в некоторых ситуациях (особенно в сценариях с адресным хранением), но, возможно, не в вашем конкретном случае.


4
Я предполагаю, что это потому, что OP не спрашивал: как мне «кодировать [мой] собственный алгоритм генерации UUID вместо вызова функциональности генерации UUID, которую предоставляют большинство современных операционных систем?»
anregen

Кроме того, я думаю, что это хорошее объяснение UUIDv3 и v5. Смотрите мой ответ ниже о том, почему я думаю, что v1 может быть хорошим выбором.
anregen

что такое NAMESPACE_URL? это переменная, которую я могу получить? отсюда?
stackdave

@stackdave NAMESPACE_URL- это UUID, обычно равный 6ba7b811-9dad-11d1-80b4-00c04fd430c8, в соответствии с рекомендацией, приведенной на стр. 30 RFC-4122 .
Джейми Риддинг

2

Документация Postgres описывает различия между UUIDs. Парочка из них:

V3:

uuid_generate_v3(namespace uuid, name text) - Эта функция генерирует UUID версии 3 в заданном пространстве имен, используя указанное имя ввода.

V4:

uuid_generate_v4 - Эта функция генерирует UUID версии 4, который полностью получен из случайных чисел.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.