Яку версію UUID використовувати?


332

Яку версію UUID слід використовувати? Я бачив багато тем, що пояснюють, що стосується кожної версії, але у мене виникають труднощі з'ясувати, що найкраще для яких програм.


2
Який ваш вибір?
Гейб

Все, що працює з пітоном. Тож я думаю, що це docs.python.org/2/library/uuid.html . 1,3,4,5.
user1802143

Якщо вам цікаво версії 3 та 5, перегляньте це питання, генеруючи v5 UUID. Що таке ім’я та простір імен? .
Василь Бурк

Відповіді:


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 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, можуть збігатися. Тільки тому, що існує багато варіантів, це не означає, що вам доведеться вичерпати унікальні параметри, перш ніж створити повтор. Це могло статися в будь-який час.
Анреген

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

31
V4 "може" стикатися, але ймовірність є винятково низькою, що для більшості випадків використання є ризиком. Re: "Дві машини у світі врешті-решт створюють один і той же" UUID'v4 ", звичайно, але це не проблема, оскільки більшість машин у світі, які використовують UUID, використовують їх у різних контекстах. Я маю на увазі, якщо я генерую той самий UUID для власного внутрішнього додатка, як і для вашого внутрішнього додатка, це не має значення. Зіткнення мають значення лише в тому випадку, якщо вони трапляються в одному контексті. (пам’ятайте, навіть у програмі багато UUID не повинні бути унікальними для всього додатка, лише контексту, в якому вони використовуються)

6
Отже, це здається, що якщо вам не потрібен ваш Посібник для захисту, використовуйте версію 1. Якщо вам потрібна безпека, і відчуваєте, що пощастить (або насправді не відчуваєте себе
нещастю

16

Це дуже загальне питання. Одна відповідь: "залежить від того, який тип UUID ви хочете створити". Але кращий такий: "Ну, перш ніж я відповім, чи можете ви сказати нам, чому потрібно кодувати свій власний алгоритм генерації UUID, а не викликати функціональність покоління UUID, яку надає більшість сучасних операційних систем?"

Робити це простіше і безпечніше, і оскільки вам, мабуть, не потрібно генерувати власні, навіщо турбуватися про кодування програми? У такому випадку відповідь стає використаною незалежно від того, що надає ваш O / S, мова програмування або рамки. Наприклад, в Windows є CoCreateGuid або UuidCreate або одна з різних обгортків, доступних з численних використовуваних рамок. У Linux є uuid_generate .

Якщо вам, з якоїсь причини, абсолютно потрібно генерувати свої власні, то, принаймні, маєте хороший сенс триматися подалі від генерування U1 та v1 та v2. Це складно виправити це правильно. Натомість дотримуйтесь UUIDs v3, v4 або v5.

Оновлення : У коментарі ви згадуєте, що використовуєте Python та посилаєтесь на це . Переглядаючи наданий інтерфейс, найпростішим варіантом для вас було б генерувати v4 UUID (тобто такий, створений з випадкових даних) шляхом виклику 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 буде відрізнятися від V5 UUID для тієї ж URL-адреси, яка генерується так:

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

Приємною властивістю URL-адрес v3 та v5 є те, що вони повинні бути сумісними між реалізаціями. Іншими словами, якщо дві різні системи використовують реалізацію, яка відповідає RFC4122, вони (або принаймні повинні ) обидва генерують один і той же UUID, якщо всі інші речі рівні (тобто генерують одну і ту ж версію UUID, з тим же простором імен та ті самі дані). Ця властивість може бути дуже корисною в деяких ситуаціях (особливо в сценаріях зберігання, адресованих вмістом), але, можливо, не у вашому конкретному випадку.


4
Я б здогадувався, що це тому, що ОП не запитував: як я "кодую [свій] власний алгоритм генерації 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.