Зіткнення UUID [закрито]


33

Хто-небудь проводив реальне дослідження щодо ймовірності зіткнень UUID, особливо з версіями 4 (випадкових) UUID, враховуючи, що генератори випадкових чисел, які ми використовуємо, не є справді випадковими, і що ми можемо мати десятки чи сотні однакових машин, що працюють з тим самим кодом генерування UUID?

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


4
На запитання вже відповіли на "Переповнення стека": stackoverflow.com/questions/3038023/… , як показано основний пошук у Google: google.com/search?q=uuid+collision
Арсеній Муренко

3
Це питання стосується конкретних алгоритмів, що використовуються в SQL * Server, який, безумовно, НЕ є версією 4 (випадковою). Я запитую конкретно про версію 4.
Пол Томблін

Ви хочете сказати, що реалізація NEWID()функції SQL Server не є випадковою? Якщо так, чи є у вас джерела для резервного копіювання такої претензії? Його результат чітко виглядає як v4 UUID для мене. NEWSEQUENTIALID()це, очевидно, не зовсім випадково, але це його мета : генерувати UUID, які добре працюють (як і UUID, можуть, принаймні), як індексні ключі.
CVn

1
Я переходжу до відповіді на пов'язане запитання, в якому зазначено, що NEWID () містить деякі біти адреси mac, що робить його V1 або V2 UUID, а не V4.
Пол Томблін

2
Це питання видається поза темою, оскільки йдеться про щось, що вже обговорювалося ad-nauseum в Інтернеті, в книгах і особливо в StackOverflow

Відповіді:


18

У Вікіпедії є деякі деталі:

http://en.wikipedia.org/wiki/Universally_unique_identifier

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

Але ймовірність має місце лише в тому випадку, якщо біти є абсолютно випадковими. Однак RFC http://tools.ietf.org/html/rfc4122#page-14, пов'язаний в іншій відповіді, визначає це для версії 4:

"4.4. [...] Версія 4 UUID призначена для генерації UUID з справді випадкових чи псевдовипадкових чисел. [...] Встановіть усі інші біти на випадково (або псевдо випадковим чином) обрані значення."

Це в значній мірі дозволяє все, від випадкового генератора xkcd http://xkcd.com/221/ до апаратного пристрою, що використовує квантовий шум. Міркування безпеки в RFC:

"6. Розподілені програми, що генерують UUID на різних хостах, повинні бути готові покладатися на джерело випадкових чисел у всіх хостів. Якщо це неможливо, слід використовувати варіант простору імен."

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


11

Ви, безумовно, повинні виявити, якщо трапиться зіткнення, і ваша програма повинна викинути виняток, якщо це сталося. Наприклад, якщо UUID використовується в якості основного ключа в базі даних, тоді база даних повинна видавати помилку під час вставки ідентифікатора, що стикається.

Однак я вважаю, що написання коду для створення нового UUID у випадку зіткнення та спроби знову бути марною тратою часу. Шанс виникнення зіткнення настільки малий, що кидання винятку було б цілком розумним способом боротьби з ним.

Пам'ятайте, що це не лише витрата власного часу на написання коду, але й робить його складнішим, ускладнюючи читати наступну людину, бо майже не отримує жодної вигоди.


2
ваш UUID такий же хороший, як і ваш випадковий генератор. При дуже ( дуже ) поганому зіткненні не тільки відбудуться, але й неминучі. Це сказало, можливо, перевірка дублікатів під час покоління справді буде надмірною, але очікувати, що ситуація може статися і, на мою думку, не так сильно вимагати. У деякому домені (наприклад, охорона здоров'я) я ​​вважаю, що необхідно мати код, який сприймає такі ситуації (можливо, як виявлення зіткнень у базі даних). ви були б здивовані, скільки часу я провів налагодження ситуацій, які ніколи не трапляються.
ньютопський

1
Я думаю, я не дав про себе зрозуміти. Я оновив відповідь, щоб бути більш чітким.
Піт

7

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

Пропозиція: дуже уважно ступайте тут і добре знайте свою криптографію. Якщо ви використовуєте 128-розрядний UUID, "ефект від дня народження" говорить нам про те, що зіткнення вірогідне після того, як ви створили приблизно 2 ^ 64 ключі, за умови, що у вас є 128 біт ентропії в кожній клавіші .

Насправді досить складно забезпечити, що це так. Справжня випадковість може бути породжена (a) радіоактивним розпадом (b) випадковим фоновим радіо шумом, часто забрудненим, якщо ви не обережні (c) належним чином обраний електронний шум, наприклад, взято з реверсивно зміщеного стабілітрону. (Я грав з останнім, і це працює як шарм, BTW).

Я б не довіряв вимовам на кшталт "Я цього не бачив за рік використання", якщо користувач не створив щось, що наближається до клавіш 2 ^ 64 (тобто приблизно 10 ^ 19), і не перевірив їх один на одного, a нетривіальна вправа.

Проблема в цьому. Скажімо, у вас всього 100 біт ентропії, порівнюючи ваші ключі з усіма іншими ключами, які всі інші генерують у загальному просторі клавіш. Ви почнете бачити зіткнення приблизно в 2 ^ 50, тобто. приблизно 10 ^ 15 клавіш. Ваші шанси побачити зіткнення, якщо ви заселили свою базу даних лише у 1000 мільярдів ключів, все ще незначні. І якщо ви не перевірите, то пізніше ви отримаєте несподівані помилки, які прокрадаються у вашу базу даних розміром з п'яти рядками. Це могло б сильно вкусити.

Сам факт наявності декількох підходів до створення таких UUID повинен викликати миттєвий спазм занепокоєння. Коли ви усвідомлюєте, що мало хто з генераторів використовує «справді випадкові» процеси з достатньою ентропією для UUID типу 4, ви повинні надто хвилюватися, якщо ви ретельно не вивчили вміст ентропії генератора. (Більшість людей цього не зробить і навіть не знає, як це зробити; ви можете почати з набору DieHarder). НЕ плутати генерацію псевдовипадкових чисел із справжнім генерацією випадкових чисел.

Важливо, що ви усвідомлюєте, що введена вами ентропія - це ентропія, яка у вас є, і просто збурення ключа, застосовуючи криптографічну функцію, не змінює ентропію. Можливо, не очевидно, що якщо весь мій простір містить цифри 0 та 1, вміст ентропії такий самий, як у наступних двох рядків, за умови, що вони є єдиними двома варіантами: "Це дійсно дійсно складний рядок 293290729382832 * ! @@ # & ^% $$) ,. m} "та" І СЕЙЧАС ДЛЯ НЕЩОГО ПОЛІЗНОГО РІЗНОГО ". Є ще лише два варіанти.

Випадковість складна, щоб виправитись, і просто вважати, що "експерти це подивилися, тому це нормально" може бути недостатньо. Експертні криптографи (а їх мало хто з тих, хто справді досвідчений) першими визнають, що вони часто помиляються. Ми довіряли сердечному сервісу, DigiNotar тощо.

Я думаю, що Пол Томблін проявляє відповідну обережність. Мій 2с.


6

Проблема у вас полягає в тому, що якщо ви використовуєте "Генератор випадкових чисел" і не знаєте, наскільки випадковий цей генератор, то ймовірність зіткнення насправді невідома. Якщо генератори випадкових чисел якимось чином співвідносяться, ймовірність зіткнення може різко зрости - можливо, багато, багато порядків або величини.

Навіть якщо у вас дуже мала ймовірність зіткнення, у вас є принципова проблема: Ймовірність НЕ 0. Це означає, що зіткнення ВИКОНУТЬСЯ, вони просто не трапляться дуже часто.

Чим частіше ви генеруєте та використовуєте UUID, тим швидше буде помічено зіткнення. (генерувати 1 рік на рік означає довший час очікування, ніж генерувати мільйон в секунду; всі інші речі рівні).

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

У вас може бути гірший випадок, знову ж таки, залежно від вашої заявки. Якщо ви перевірите наявність UUID (тобто зробите пошук), а потім зробите новий, якщо його ще немає - що є досить поширеною справою, - ви можете виявити, що ви зв'язуєте записи або встановлюєте зв’язки , насправді ви підключаєте дві речі через UUID, які не слід підключати. Це щось, коли кидання винятку нічого не вирішить, і у вас десь створений нерозбірливий безлад. Це та річ, яка призводить до витоку інформації і може бути дуже незручною. (наприклад: Увійдіть у свій банк і знайдете, що ви бачите залишки на рахунку когось іншого! Погано!)

Підсумок: вам потрібно врахувати спосіб використання ваших UUID та наслідки зіткнення. Це визначає, чи слід подбати про виявлення та уникнення зіткнень, вчинити прості дії у разі зіткнення чи нічого не робити. Просте, єдине, універсальне рішення, за певних обставин, ймовірно, буде недоцільним.


2
"Ймовірність (зіткнення) НЕ 0" Будь-яка послідовність кінцевої довжини має цю властивість. Навіть із ідеально випадковим v4 UUID, коли ви створили 2 ^ 122 унікальних UUID (128 біт мінус 4 біт версія мінус 2 зарезервовані біти), наступний, який ви генеруєте, гарантовано стане зіткненням. Швидше за все, ви зіткнулися зіткненням раніше. Більш важливим питанням є те, чи зіткнення після чогось подібного 5e36 повторів є проблемою, і на це не можна відповісти загалом (хоча, очевидно, можна відповісти у кожному конкретному випадку), як ви говорите в резюме.
CVn

Звичайно. Це було очевидним твердженням (але все ще повторюється). Питання полягає в тому, наскільки співвідношення є генераторами випадкових чисел. Це може значно збільшити ймовірність зіткнення (2 ^ великі), але наскільки це те, чого ви не знатимете, якщо ви не зробите багато копання, досліджень чи розрахунків. Якщо припустити, що ймовірність зіткнення значно гірша, ніж найкраще значення, мабуть, доцільне. Після цього ... потім потрібно розглянути наслідки.
швидко_віз

0

Є два питання:

  1. Якість генераторів випадкових чисел, які використовуються.

  2. Кількість UUID, які можуть бути створені.

"Випадковий" UUID має 122 випадкових біта. Якщо припустити ідеальну випадковість, ви можете очікувати першого зіткнення приблизно в 2 ^ 61 породжених UUID (це квадратний корінь 2 ^ 122). Якби всі на цій землі генерували UUID в секунду, це 10 000 000 000 * 365 * 24 * 60 * 60 = 315360000000000000 UUID на рік, що досить близько до 2 ^ 58. Тобто через кілька років у вас виникнуть перші зіткнення. Якщо ваша програма не опиниться поблизу цих номерів, ви можете бути впевнені, що ви не зіткнетесь, якщо ваш випадковий генератор гідної якості.

Якщо говорити про генератор випадкових чисел: Якщо ви використовуєте стандартні генератори бібліотек С (безпосередньо, опосередковано або подібні генератори), ймовірно, висіваючи їх з часом, ви закручуєтесь. Вони не можуть мати достатню кількість ентропії, щоб уникнути зіткнень. Однак якщо ви користуєтесь Linux, просто прочитайте 16 байт даних з /dev/urandom: Це спирається на пул ентропії, який перемішується ядром, який має доступ до деяких реальних випадкових подій. Якщо ви зазвичай не генеруєте UUID, дійсно, дуже рано послідовність завантаження /dev/urandomповинна поводитись як справжнє випадкове джерело.


-1

Я тестував це один раз, використовуючи досить просту (грубу силу) програму, яка генерувала 10 мільйонів UUID -ів, і я не зазнав зіткнення.

UUID RFC каже , що UUID не просто купа (псевдо) випадкових чисел.


1
Версія 4, про яку я запитую, в значній мірі - це купа випадкових чисел, за винятком 6 біт, які будуть однаковими у всіх.
Пол Томблін

8
10 мільйонів - це навіть не крапля відра. Є лише шанс зіткнення 1 на 3E30. Якщо ви знайшли його, я б порадив вам поспішати та купувати квиток у кожній можливій лотереї!
Росс Паттерсон

@RossPatterson, що мене конкретно цікавило, чи є у вас кілька сотень комп’ютерів, що використовують той самий той же алгоритм psuedo-випадкових випадків на одному і тому ж апараті, різко збільшує шанси зіткнення. Я підозрюю, що це буде.
Пол Томблін

1
@Paul - Я б подумав, лише якщо в початковому процесі висіву недостатньо ентропії - наприклад, якщо насіння генерується лише з дня доби, і всі ваші машини запустилися в один і той же момент. Я дуже сумніваюся, що посів насіння такий слабкий - навіть можливо, що використовуються серійні номери обладнання, що, звичайно, було б унікальним для кожної машини.
Steve314

1
На жаль, насіння може бути дуже слабким. Системи Linux люблять висівати PRNG з високо випадкових джерел (активність драйверів пристроїв тощо ), але в інших середовищах стандартним є використання поточної мітки часу, яка може мати проблему з достатньою кількістю машин, що знаходяться у близькій синхронізації часу.
Росс Паттерсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.