Возможны ли конфликты GUID?


128

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


11
Все говорят, что нет - это неправильно. Я уже столкнулся с 1 UniqueIdentifier с набором данных менее полумиллиона записей, MSSQL 2008 R2
Behrooz

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

6
@Behrooz Вау. Это шокирующая удача.
Craig Ringer

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

3
Мне нравится, как именно в этот момент и вопрос, и выбранный ответ имеют 128 баллов. Стечение обстоятельств? 🤔
Caio Cunha

Ответы:


128

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

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


3
Я так и подумал, но просто хотел убедиться, что не могу этого исключить. Вы никогда не знаете, какие странные ошибки могут появиться в программах 8-летней давности. :)
Джейсон Бейкер

6
На самом деле это уже не так. Это было верно для GUID v1, но не для текущих v4. См. En.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm для получения дополнительной информации.
Грег Бич

98
Голосование против, потому что, в принципе (в самой грубой форме), вы ошибаетесь, говоря «нет» на вопрос «Возможны ли конфликты GUID?». Вполне возможно. Вероятность чего мала, но это возможно. Ненавижу казаться педантичным, но SO - это все, чтобы быть кратким и точным.

13
введите "решить [1-exp [- (n ^ 2 / (2 * 2 ^ 128))]> 0,01, n]" в вольфрам-альфа, чтобы получить результат для 1% ... Помните, что, хотя это число кажется большим в контекст ОДНОГО приложения, он определенно невелик для всего мира. Если каждый компьютер на Земле будет генерировать истинные идентификаторы GUID, они вызовут коллизию с вероятностью 1% в течение примерно одной секунды, если предположить, что они могут генерировать GUID каждую наносекунду (что, вероятно, вполне реально в наши дни). Поэтому, если вы используете идентификаторы GUID для идентификаторов своей базы данных, они уникальны. Идентификаторы GUID для каждого вычисления, выполняемого на Земле, немедленно столкнутся.
thesaint

11
Сказать «Нет», это невозможно, а затем сказать, что вероятность столкновения составляет 1% при генерации определенного количества, - это прямые конфликты. Теоретически правильный ответ должен быть - да, столкновение могло произойти случайно. Однако шансы столкновения статистически меньше, чем у астероида, ударившегося о Землю, отскочив от нее и отскочив от Луны, чтобы ударить Землю во второй раз, в течение следующего часа.
Baaleos

112

В принципе это невозможно! , шансы астрономически низкие .

Но ... Я единственный человек в мире, о котором я знаю, у которого однажды была коллизия GUID (да!).

И я уверен в этом, и что это не было ошибкой.

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

Изменить: есть некоторые факторы, которые могли значительно увеличить вероятность этого, приложение работало на эмуляторе PocketPC, а в эмуляторе есть функция сохранения состояния, что означает, что каждый раз, когда состояние восстанавливается, также восстанавливается местное время и guid основан на внутреннем таймере .... также алгоритм генерации guid для компактной структуры может быть менее полным, чем, например, COM ...


38
Upvoted. При сохранении состояния и воспроизведении действительно будут генерироваться повторяющиеся направляющие.
Джошуа

35
Скорее всего, это была «плохая» реализация GUID. Эти теоретические шансы были очень низкими, а на Pocket PC ?? Кто сказал, что они не пошли по пути, который поднял эти шансы до категории «маловероятно, но возможно».
Дэйв Допсон

9
Тот факт, что вероятность того, что что-то произойдет, очень мала, не означает, что этого не произойдет.
Renan

3
Как я сказал выше, шансы на это настолько малы, что можно с уверенностью предположить, что либо вы допустили ошибку, либо MSSQL использует дефектный PRNG ( en.wikipedia.org/wiki/Pseudorandom_number_generator ). Например, вполне вероятно, что этот ГПСЧ инициализируется семенем небольшого размера. Дефектные ГПСЧ не редкость (см. Schneier.com/paper-prngs.html ) - например, один дефект был недавно обнаружен в Android SDK - android-developers.blogspot.com/2013/08/… + usenix.org/conference/woot14 / программа-мастерская / презентация /…
Alex

2
@Alex, ошибка была "Сохранить состояние и восстановить" из эмулятора, которые восстанавливают весь образ эмулятора, включая часы эмулятора. Таким образом, после тысяч операций восстановления в течение одного года возникла одна коллизия направляющих. Вы правы, произошла ошибка!
Pop Catalin

34

Теоретически они возможны, но с возможными числами 3.4E38, если вы создаете десятки триллионов GUID в год, вероятность иметь один дубликат составляет 0,00000000006 ( Источник ).

Если у двух пользователей будет одинаковый GUID, я готов поспорить, что в программе есть ошибка, которая приводит к копированию или совместному использованию данных.


«но с возможными числами 3.4Е38» - нет. Два идентификатора GUID, сгенерированные почти одновременно на одном компьютере, в конечном итоге будут иметь очень похожие идентификаторы GUID.
Кирк Штраузер

4
Это будет зависеть от того, как генерируется GUID, и некоторые реализации, основанные на времени процессора или миллисекундах, будут (надеюсь) преувеличивать любые вычисления, на которых он основан, поэтому два GUID, сгенерированные с интервалом в миллисекунды, будут иметь огромную разницу.
Далин Сейврайт,

4
При наличии более 1 процессора на машине, если guid основан на времени и MAC-адресе, тогда каждое ядро ​​может выдавать один и тот же guid в один и тот же момент времени.
AndyM

12
Я почти уверен, что никакой достойной реализации GUID не будет
Guillaume86

1
@MatthewLock Парадокс дня рождения раскрыт в источнике. Проверить ссылку.
Zero3

21

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

Также обратите внимание, что идентификаторы GUID не содержат отметку времени или MAC-адрес, как многие люди, похоже, также считают. Это было верно для идентификаторов GUID v1, но теперь используются идентификаторы GUID v4, которые представляют собой просто псевдослучайное число, что означает, что вероятность столкновения, вероятно, выше, поскольку они больше не уникальны для времени и машины.

Итак, по сути, ответ - да, столкновения возможны. Но они маловероятны.

Изменить: исправлено, чтобы сказать 2 ^ 64


2
Хотя я согласен со всеми вашими фактами, будьте осторожны с расчетами. Сказать, что вероятность столкновения любых двух идентификаторов GUID составляет 1 из 10 ^ 19, зависит от количества идентификаторов 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-адреса, особенно в базах данных, поскольку они имеют желаемые характеристики. См. UuidCreateSequential и его оболочку 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 статистически уникальны, а данные, которые вы читаете из базы данных, верны только статистически.


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

13

В этом случае я бы считал бритву Оккама хорошим ориентиром. Маловероятно, что у вас есть конфликт GUID. Гораздо более вероятно, что у вас есть ошибка или кто-то испортил ваши данные.


1
На самом деле в этой ситуации бритва Оккама - совсем не лучший помощник! Бритва Оккама говорит, что случай с наименьшими предположениями, скорее всего, будет правильным. В этой ситуации случай столкновения GUID на самом деле намного проще, но бритва Оккама неприменима к такой ситуации, когда мы уже знаем, что один из случаев невероятно маловероятен.
lockstock

11

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

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

Теперь идентификаторы GUID тщательно спроектированы так, чтобы быть по имени глобально уникальными, поэтому я рискую, что это невозможно или с очень очень низкой вероятностью. Я бы поискал в другом месте.





9

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


Часто ли два разных компьютера имеют один и тот же MAC-адрес Ethernet?
Dave Lucre

@DaveLucre: Нет, но инциденты были зарегистрированы.
Джошуа

Мне действительно любопытно, как это происходит. Это более вероятно с виртуальными машинами, которые случайным образом генерируют MAC для каждой сетевой карты? Я никогда не слышал о производстве физических сетевых адаптеров с дублированными MAC! Это вроде как бросает в работу огромный гаечный ключ, если это возможно!
Dave Lucre

Вот Это Да! Спасибо за ссылку @Joshua! Какой колоссальный провал!
Dave Lucre

@DaveLucre Я использовал несколько очень дешевых USB-адаптеров, ВСЕ из которых производятся с одним и тем же MAC. Но, конечно же, это не имеет ничего общего с математикой случайности, а все связано с ленью производителя.
rudolfbyker 03

5

Я предваряю это словами: «Я не занимаюсь сетями, поэтому я могу сделать после него совершенно бессвязные предложения».

Когда я работал в Университете штата Иллинойс, у нас было два настольных компьютера Dell, заказанных в разное время. Мы поместили первый в сеть, но когда мы попытались подключить вторую, мы начали получать сумасшедшие ошибки. После долгого устранения неполадок было определено, что обе машины выдавали один и тот же GUID (я не уверен, зачем, но это сделало их непригодными для использования в сети). Dell фактически заменила обе машины как неисправные.


3
Это был конкретно GUID. Это как-то связано с GUID, сгенерированным машинами, когда они присоединяются к сети. Dell потребовалось несколько недель, чтобы заменить машины, потому что они заявили, что идентификаторы GUID не могут совпадать. Нам удалось воспроизвести проблему, Dell забрала машины и добилась таких же результатов в своих сетях. В итоге они заменили обе машины. Как я уже сказал, я не специалист по сетям, но я специально помню, что это была проблема с GUID.
Джон Крафт,

5

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


11
Также рекомендую не использовать сети. Или компьютеры. Биты четности способны на многое!
Rushyo 03

Ты не понял. В этом посте я пытался сказать две вещи: 1) Если вам нужно большое случайное число, используйте большое случайное число. Использование GUID в качестве большого случайного числа напрасно вводит в заблуждение. (2)
Рик Йоргасон

4
Что я полностью осознаю. Вы заявили: «Если вам неудобно использовать большое случайное число». но идентификаторы GUID настолько уникальны, что вы обнаружите, что почти все остальное на компьютере более случайное, даже операции, которые вы принимаете как должное. У вас больше шансов, что сбой с памятью сломает ваш столбец идентификаторов, чем столкновение (истинного) GUID. Вы не должны чувствовать себя неловко из-за них. Если они не идеальны для сценария, тогда все в порядке, но они не нуждаются в особой осторожности.
Rushyo,

3
Я предполагаю, что это никуда не денется, но люди пытаются объяснить вам, что механизмы обнаружения ошибок в обычном оборудовании, таком как сетевые карты или жесткие диски, используют алгоритмы, которые имеют больше шансов не обнаруживать ошибку, чем вы, чтобы получить коллизию GUID, поэтому, если вы полагаетесь на них, вы также можете полагаться на GUID
Guillaume86

1
@ Рик, это зависит от того, насколько велик твой номер. Определенно не с 4-байтовым int или 8-байтовым bigint. GUID = 16 байт, поэтому для достижения тех же самых возможных комбинаций 2 ^ 128 потребуется специальная реализация большого числа 16 байт. Так , вообще говоря, при использовании «нормальный» 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.