Чи можливі зіткнення GUID?


128

Я працюю над базою даних в SQL Server 2000, яка використовує GUID для кожного користувача, який використовує додаток, до якого він пов'язаний. Якось двоє користувачів опинилися з тим самим GUID. Я знаю, що мікрософт використовує алгоритм для створення випадкового GUID, який має надзвичайно низький шанс викликати зіткнення, але чи можливе зіткнення?


11
Усі говорять "не помиляються". Я вже зіткнувся 1 UniqueIdentifier з набором даних менше півмільйона записів, MSSQL 2008 R2
Behrooz

2
@Behrooz Yikes. Це не неможливо завдяки парадоксу на день народження нашого друга, але він все ще шалено невдалий з повністю випадковими GUID-кодами v4. Можливо, ви використовували слабку стратегію генерації GUID?
Крейг Рінгер

6
@Behrooz Нічого собі Це шокуюча удача.
Крейг Рінгер

6
@Behrooz це, мабуть, несправне псевдо випадкове число, яке використовується в MSSQL (я не здивуюсь, якщо у їх генераторі є 32-бітове насіння або подібне, враховуючи якість свого програмного забезпечення). Математика не бреше. Ця можливість настільки мала, що ви можете отримати 99,9999999999 (і багато 9 після)%, що або генератор MSSQL-орієнтирів несправний (або може бути псевдовипадковий генератор, який використовується для створення GUID), або ви помилилися.
Олексій

2
Любіть, як в цей момент і питання, і обрана відповідь мають 128 балів. Збіг? 🤔
Кайо Кунья

Відповіді:


127

В основному, ні. Я думаю, що хтось зазіхав на вашу базу даних. Залежно від GUID версії, яку ви використовуєте, значення є або унікальним (для речей, як GUID версії 1), або унікальним і непередбачуваним (для речей, як GUID версії 4). Реалізація SQL Server для їх функції NEWID (), як видається, використовує 128-бітове випадкове число, тому зіткнення не збирається.

Для шансу зіткнення на 1% вам потрібно створити близько 2 600 000 000 000 000 000 GUID.


3
Це я зрозумів, але я просто хотів переконатися, що я не можу цього виключити. Ніколи не знаєш, які види дивних помилок можуть з’являтися у 8-річному програмному забезпеченні. :)
Джейсон Бейкер

6
Насправді це вже не так. Це було вірно для v1 GUID, але не для поточних v4. Для отримання додаткової інформації див. En.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm .
Грег Бук

97
Проголосуйте проти, оскільки, в принципі (у найсуміснішій формі), ви неправильно говорите "ні" на запитання "Чи можливі колізії GUID?". Це дуже можливо. Ймовірність цього невелика, але це можливо. Я ненавиджу звучати педантично - але ТАК у тому, щоб бути стислим і точним.

13
введіть "вирішити [1-exp [- (n ^ 2 / (2 * 2 ^ 128))]> 0,01, n]" в альфа-вольфрам, щоб отримати результат на 1% ... Майте на увазі, що хоча ця кількість здається великою в контекст програми ONE, він, безумовно, не великий для всього світу. Якщо кожен комп'ютер на Землі генерував би справжні GUID, вони спричинили зіткнення з 1% -ною ймовірністю протягом приблизно однієї секунди, припускаючи, що вони можуть генерувати GUID кожну наносекунду (що, мабуть, цілком реально в ці дні). Тож якщо ви використовуєте GUID для ідентифікаторів вашої бази даних, вони унікальні. GUID для кожного обчислення, зробленого на землі, зіткнеться негайно.
thesaint

11
Сказати "ні" це неможливо, а потім сказати, що існує 1% шанс отримати зіткнення, коли певна сума генерується, - це прямі конфлікти. Правильна відповідь повинна бути теоретично - так, зіткнення може статися випадковим чином. Однак шанси на зіткнення статистично менші, ніж астероїд ударить про Землю, відскакуючи від Землі та відскочивши від Місяця, щоб ударити Землю вдруге, у наступній годині.
Baaleos

112

В основному вони не можливі! , шанси астрономічно низькі .

Але ... я єдина людина, про яку я знаю у світі, яка колись мала колізію GUID (так!).

І я впевнений у цьому, і що це не помилка.

Як це сталося, в невеликому додатку, який працює на Pocket PC, наприкінці операції повинна бути видана команда, що має сформований GUID. Команда після її виконання на сервері зберігалася в таблиці команд на сервері разом із датою виконання. Одного разу під час налагодження я видав команду модуля (із доданим нещодавно створеним GUID), і нічого не сталося. Я зробив це ще раз (з тією ж інструкцією, тому що на початку операції було створено лише один раз), і знову, і нічого, нарешті, намагаючись з’ясувати, чому команда не виконується, я перевірив таблицю команд, і той самий GUID, що і поточний, було вставлено 3 тижні тому. Не вірячи в це, я відновив базу даних із резервного копіювання за два тижні, і настанова була там. Перевіривши код, нова вказівка ​​була щойно створена без сумнівів.

Редагувати: є деякі фактори, які могли б значно збільшити шанси на те, що це станеться, програма працювала на емуляторі PocketPC, а емулятор має функцію збереження, що означає, що кожен раз, коли стан відновлюється, відновлюється також місцевий час і керівництво базується на внутрішньому таймері .... також алгоритм генерації орієнтирів для компактних фреймів може бути менш повним, ніж, наприклад, COM ...


38
Отримано. Збереження стану та повторної дії справді створило б повторювані посібники.
Джошуа

35
Ймовірно, що це сталося, це була "погана" реалізація GUID. Ці теоретичні шанси були дуже низькими, а на Pocket PC ?? Хто скаже, що вони не скористалися ярликом, який нарізав ці шанси на категорію "малоймовірна, але можлива".
Дейв Допсон

9
Тільки тому, що щось має дуже низьку ймовірність, це не означає, що це не відбудеться.
Ренан

3
Як я вже говорив вище, шанси на це настільки малі, що можна припустити, що ви або помилилися, або MSSQL використовує несправний PRNG ( en.wikipedia.org/wiki/Pseudorandom_number_generator ). Наприклад, цілком імовірно, що цей PRNG ініціалізується насінням невеликих розмірів. Несправні PRNG не рідкісні (див. Schneier.com/paper-prngs.html ) - наприклад, один дефект був нещодавно виявлений в Android SDK - android-developers.blogspot.com/2013/08/… + usenix.org/conference/woot14 / семінар-програма / презентація /…
Олексій

2
@Alex, помилкою було "Зберегти стан та відновити" з емулятора, які відновлюють все зображення емулятора, включаючи тактовий час емулятора. Тож після тисяч операцій по відновленню протягом року було створено одне колізійне зіткнення. Ви праві, сталася помилка!
Поп Каталін

34

Вони теоретично можливі, але при 3.4E38 можливих цифр, якщо ви створюєте десятки трильйонів GUID за рік, шанс отримати один дублікат 0,00000000006 ( Джерело ).

Якби двоє користувачів опинилися з однаковим GUID, я б став на загрозу, що в програмі є помилка, яка спричиняє копіювання або обмін даними.


"але з 3.4E38 можливими цифрами" - ні. Два GUID, згенеровані майже одночасно на одній машині, мали б надзвичайно подібні GUID.
Кірк Штраузер

4
Це залежатиме від того, як генерується GUID, і деякі реалізації, що базуються на час або мілісекундах процесора, (сподіваємось), перебільшують будь-який обчислення, виходячи з нього, так що два GUID, що генеруються на відстані мілісекунд, матимуть величезну різницю.
Dalin Seivewright

4
Якщо на комп'ютері є більше 1 процесора, якщо орієнтир базується на часу та mac-адресі, то кожне ядро ​​могло б видати одне і те ж керівництво в той самий момент часу.
AndyM

12
Я впевнений, що будь-яка гідна реалізація GUID не буде
Guillaume86

1
@MatthewLock Парадокс дня народження висвітлюється у джерелі. Перевірте посилання.
Нуль3

21

Спочатку давайте розглянемо шанс зіткнення двох GUID. Як сказано в інших відповідях, це не парадокс від дня народження 1 в 2 ^ 128 (10 ^ 38) , а це означає, що для 50% шансу зіткнення двох GUID-імовірностей насправді 1 на 2 ^ 64 (10 ^ 19) що набагато менше. Однак це все-таки дуже велика кількість, і тому така ймовірність зіткнення, припускаючи, що ви використовуєте розумну кількість GUID, є низькою.

Зауважте також, що GUID не містять позначки часу або MAC-адреси, оскільки, здається, багато людей також вважають. Це було справедливо для v1 GUID, але тепер використовуються v4 GUID, які є просто псевдовипадковим числом, що означає, що можливість зіткнення, можливо, вище, оскільки вони вже не унікальні для часу та машини.

Отже, по суті, відповідь "так", можливі зіткнення. Але вони малоймовірні.

Редагувати: зафіксовано, щоб сказати 2 ^ 64


2
Хоча я згоден з усіма вашими фактами, будьте обережні зі своєю математикою. Сказати, що у вас є шанс 1 на 10 ^ 19 зіткнення будь-яких двох GUID, залежить від кількості GUID в наборі. Для цього шансу вам потрібно ~ 2 ^ 32 GUID, тому майже у всіх реальних сценаріях шанси значно нижчі.
DocMax

1
У вас є помилка друку 1 in 10^64 (10^19), якою я думаю, що має бути 1 in 2^64 (10^19). Я також дуже розгублений, як ви думаєте, що парадокс дня народження стосується лише двох номерів. Я припускаю, що ви подивилися на en.wikipedia.org/wiki/Birthday_paradox . У таблиці показано, скільки посібників вам потрібно для заданої ймовірності дубліката. З цієї таблиці для ймовірності 1 на 10 ^ 18 потрібні 2,6 * 10 ^ 10 посібників, що не є близьким лише до двох GUID.
Тоні Лі

Один момент - посібники v1 досі знаходяться у широкому використанні та покладаються на MAC-адресу, особливо в базах даних, оскільки вони мають бажані характеристики. Див. UuidCreateSequences і його обгортку SQL Server NewSequentialID ( msdn.microsoft.com/en-us/library/windows/desktop/… ).
EBarr

18

Шанси зіткнення двох випадкових GUID (~ 1 на 10 ^ 38) нижчі, ніж шанс не виявити корумпований пакет TCP / IP (~ 1 на 10 ^ 10). http://wwwse.inf.tu-dresden.de/data/courses/SE1/SE1-2004-lec12.pdf , стор. 11. Це також стосується дисководів, компакт-дисків тощо ...

GUID є статистично унікальними, і дані, які ви читаєте з db, є лише статистично правильними.


Ви впевнені, що я не міг би броняти свою мережу, тому менше 1 з 10 ^ 28 пакетів пошкоджено?
Джошуа

13

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


1
Насправді в цій ситуації бритва Оккама зовсім не хороший посібник! Бритва Оккама говорить, що справа з найменшими припущеннями, швидше за все, є вірною. У цій ситуації випадок зіткнення GUID насправді набагато простіший, але Бритва Оккама не застосовується до такої ситуації, коли ми вже знаємо, що один із випадків неймовірно малоймовірний.
замок

11

Дивіться статтю Глобально унікальний ідентифікатор Вікіпедії . Існує кілька способів генерування GUID. Мабуть, старий (?) Спосіб користувався Mac-адресою, часовою міткою до дуже короткої одиниці та унікальним лічильником (для управління швидкими поколіннями на одному комп’ютері), тому зробити їх дублікатами майже неможливо. Але ці GUID були скасовані, оскільки їх можна було використовувати для відстеження користувачів ...

Я не впевнений у новому алгоритмі, який використовує Microsoft (у статті йдеться про те, що послідовність GUID-файлів можна передбачити, схоже, вони більше не використовують часові позначки? У статті, пов'язаній вище в Microsoft, сказано щось інше ...).

Тепер GUID ретельно розроблені таким чином, щоб вони були назви унікальними у всьому світі, тому я ризикую, що це неможливо або дуже-дуже низька ймовірність. Я б шукала в іншому місці.





9

Дві машини Win95, у яких є Ethernet-карти з подвійними MAC-адресами, видаватимуть дублікати GUIDE у жорстких контрольованих умовах, особливо якщо, наприклад, живлення відключається в будівлі, і вони обидва завантажуються рівно в один і той же час.


Чи спільно для двох різних машин однаковий MAC-адресу Ethernet?
Дейв Лукре

@DaveLucre: Ні, але інциденти зафіксовані.
Джошуа

Мені дуже цікаво, як це відбувається. Чи більш ймовірно, що для віртуальних машин випадково генерується MAC для кожного NIC? Я ніколи не чув, щоб фізичні NIC виготовлялися з дублікатами MAC! Різновид кидків, коли це можливо!
Дейв Лукре

Оце Так! Дякуємо за посилання @Joshua! Яка колосальна викрутка!
Дейв Лукре

@DaveLucre Я використовував дуже дешеві USB-картки, де всі виробляються з тим же MAC. Але, звичайно, це не має нічого спільного з математикою випадковості, і все, що стосується лінь виробника.
rudolfbyker

5

Я передмовлюся цим "Я не є мережевою особою, тому я можу зробити цілком непослідовні речення наступними".

Коли я працював в державному університеті штату Іллінойс, у нас було два настільних комп’ютери Dell, замовлені в різний час. Ми помістили першу в мережі, але коли ми спробували поставити другу в мережі, ми почали отримувати шалені помилки. Після довгого усунення несправностей було встановлено, що обидві машини виробляють однаковий GUID (я не впевнений, для чого саме, але це зробило їх обома непридатними в мережі). Dell фактично замінив обидві машини як несправні.


3
Це був саме GUID. Це мало відношення до GUID, створеного машинами, коли вони приєдналися до мережі. Dell пройшло кілька тижнів, щоб замінити машини, оскільки вони сказали, що GUID не можуть бути однаковими. Ми змогли відтворити проблему, Dell забрав машини назад і змогли створити ті самі результати у своїх мережах. Вони закінчилися заміною обох машин. Як я вже говорив, я не є мережевою особою, але спеціально пам’ятаю, що це була проблема з GUID.
Джон Крафт

5

Я знаю, що людям подобається почувати себе добре, що GUID є магічними та гарантовано унікальними, але насправді більшість GUID - це лише 121-бітові випадкові числа (сім форматів витрачається на форматування). Якщо ви не відчували себе комфортно, використовуючи велике випадкове число, то вам не слід почувати себе комфортно, використовуючи GUID.


11
Також рекомендую не використовувати мережі. Або комп’ютери. Паритети парності можуть зробити лише стільки!
Rushyo

Ви неправильно зрозуміли. У цій публікації я намагався сказати дві речі: 1) Якщо вам потрібно велике випадкове число, використовуйте велике випадкове число. Використання GUID як великого випадкового числа є непотрібним введенням в оману. (2)
Рік Йоргасон

4
Якого я цілком усвідомлюю. Ви заявили, "якби вам не зручно було використовувати велике випадкове число". але GUID настільки унікальні, що ви побачите, що майже все інше на комп’ютері є більш випадковим, навіть операції, які ви приймаєте як належне. Існує більше шансів, що збиток пам’яті виродків порушить ваш стовпець особи, ніж відбудеться зіткнення (справжнього) GUID. Ви не повинні відчувати себе 'некомфортно' щодо них. Якщо вони не ідеальні для сценарію, тоді добре - але вони не потребують особливої ​​обережності.
Rushyo

3
Я думаю, що це нікуди не діється, але те, що люди намагаються пояснити вам, - це те, що механізми виявлення помилок у звичайних апаратних засобах, таких як мережеві карти або жорсткі диски, використовують алгоритми, які мають більше шансів не виявити помилку, ніж ви отримаєте зіткнення GUID, так що якщо Ви покладаєтесь на них, ви також можете покластися на GUID
Guillaume86

1
@ Rick, залежить, наскільки велика ваша кількість. Однозначно не з 4-байтовим int або 8-байтовим бінті. GUID = 16 байт, тому вам знадобиться спеціальна реалізація великої кількості 16 байт, щоб досягти однакових 2 ^ 128 можливих комбінацій. Так , взагалі кажучи, при використанні «нормальний» Int або BigInt випадкових чисел, вірогідність зіткнень з GUID є нижче (виїзд з випадкових міркувань Algo для кожного).
Вім Холлебрандсе

3

Чи може код, який використовується для створення GUID, помилку в ньому? Так, звичайно, могло. Але відповідь така ж, як і для помилки компілятора - ваш власний код на порядок більше, імовірно, буде помилковим, тому спочатку подивіться там.


2

Звичайно, це можливо .... Ймовірно? Не ймовірно, але можливо.

Пам'ятайте, одна і та ж машина генерує кожен GUID (сервер), тому багато «випадковості», заснованої на певній машині інформації, втрачається.


1

Тільки для посмішок спробуйте наступний сценарій ... (працює на SQL 2005, не впевнений про 2000 рік)

declare @table table
(
    column1 uniqueidentifier default (newid()),
    column2 int,
    column3 datetime default (getdate())
)

declare @counter int

set @counter = 1

while @counter <= 10000
begin
    insert into @table (column2) values (@counter)
    set @counter = @counter + 1
end

select * from @table

select * from @table t1 join @table t2 on t1.column1 = t2.column1 and t1.column2 != t2.column2

Виконуючи це повторно (займає менше секунди), виходить досить широкий діапазон від першого вибору, навіть з НАДЖИВОМИ коротким часовим проміжком. Поки другий вибір нічого не дав.


1
Вам потрібно ще 15 нулів в кінці лічильника, щоб мати 50% шансів на копію. Але заради Піта цього не роби!
Джим Бірчалл

0

Неможливо, якщо користувачі мають різні машини з мережевими картами, і навіть якщо ні, це все-таки надзвичайно граничний майже теоретичний ризик.

Особисто я би зазирнув в інше місце, оскільки це швидше помилка, а не сутичка GUID ...

Звичайно, якщо ви не відсікаєте шматочки від GUID, щоб скоротити його.


GUID-файли створюватимуться на сервері, тому мережеві карти користувача не вступатимуть у дію.
Том Ріттер

0

Впевнені, що це можливо, а може, ймовірно. Це не так, як кожен GUID знаходиться у випадковій частині можливого простору чисел. У випадку, якщо дві нитки намагаються генерувати одну одночасно, забороняючи якусь централізовану функцію GUID із семафором навколо неї, вони можуть закінчитися тим самим значенням.


0

Це малоймовірно, що ви зіткнетесь із зіткненнями GUID, якщо ви генеруєте їх через щось на зразок NEWID()функції на SQL Server (хоча, звичайно, це можливо, як підкреслювали інші відповіді). Одне, на що вони не звернули увагу, - це те, що насправді цілком ймовірно, що ви зіткнетесь зіткненнями, якщо ви генеруєте GUID в JavaScript на браузерах у дикій природі. Мало того, що іноді виникають проблеми в RNG в різних браузерах, але я також стикаюся з проблемами, коли павуки Google, схоже, кешують результати таких функцій, і в кінцевому підсумку неодноразово передають той самий GUID до наших систем.

Дивіться різні відповіді тут для більш детальної інформації:

Зіткнення під час генерації UUID в JavaScript?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.