GUID 충돌이 가능합니까?


128

SQL Server 2000에서 연결된 응용 프로그램을 사용하는 각 사용자에 대해 GUID를 사용하는 데이터베이스에서 작업하고 있습니다. 어쨌든 두 명의 사용자가 동일한 GUID를 사용했습니다. Microsoft는 알고리즘을 사용하여 콜리 전을 유발할 가능성이 극히 적은 임의의 GUID를 생성하지만 충돌은 여전히 ​​가능하다는 것을 알고 있습니다.


11
나는 이미 50 만 미만의 레코드를 가진 1 개의 UniqueIdentifier를 충돌 시켰습니다. MSSQL 2008 R2
Behrooz

2
@Behrooz Yikes. 친구의 생일 역설 덕분에 불가능하지는 않지만 완전히 임의의 v4 GUID를 사용하면 여전히 운이 좋지 않습니다. 더 약한 GUID 생성 전략을 사용하고 있었습니까?
Craig Ringer

6
@Behrooz 와우. 충격적인 행운입니다.
Craig Ringer

6
@ Behrooz 이것은 아마도 MSSQL에서 사용되는 결함이있는 의사 난수 일 것입니다 (소프트웨어의 품질을 고려하여 생성기 등에 32 비트 시드가 있다면 놀라지 않을 것입니다). 수학은 거짓말하지 않습니다. 이 가능성은 너무 작아서 MSSQL guid 생성기에 결함이 있거나 (GUI를 생성하는 데 사용되는 의사 랜덤 생성기 일 수 있음) 99.9999999999 (및 많은 9 이후) % 일 수 있습니다.
Alex

2
이 정확한 순간에 질문과 선택된 답변 모두 128 점을 얻는 방법을 좋아하십시오. 우연의 일치? 🤔
Caio Cunha

답변:


127

기본적으로 누군가 당신의 데이터베이스를 다루는 것 같습니다. 버전 GUID에 따라 값을 사용하는 것이 고유하거나 (버전 1 GUID와 같은 것) 고유하거나 예측할 수없는 것 (버전 4 GUID와 같은 것)입니다. NEWID () 함수에 대한 SQL Server의 구현은 128 비트 난수를 사용하는 것으로 보이므로 충돌이 발생하지 않습니다.

충돌 가능성이 1 %이면 약 2,600,000,000,000,000,000 GUID 를 생성해야합니다 .


3
그것이 내가 생각한 것이지만, 나는 그것을 배제 할 수 없도록하고 싶었습니다. 8 살짜리 소프트웨어에서 어떤 종류의 이상한 버그가 나타나는지 알 수 없습니다. :)
Jason Baker

6
사실 그것은 더 이상 사실이 아닙니다. v1 GUID에는 해당되지만 현재 v4 GUID에는 해당되지 않습니다. 자세한 내용은 en.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm 을 참조하십시오 .
Greg Beech

97
원칙적으로 (가장 원시적 인 형식으로) "GUID 충돌이 가능합니까?" 매우 가능합니다. 가능성은 작지만 가능합니다. 나는 현명한 소리를 싫어하지만-간결하고 정확합니다.

13
wolfram alpha에 "solve [1-exp [-(n ^ 2 / (2 * 2 ^ 128))]> 0.01, n]"을 입력하여 1 %의 결과를 얻으십시오.이 숫자가 커 보이는 동안 하나의 응용 프로그램의 맥락에서, 그것은 전 세계적으로 크지 않습니다. 지구상의 모든 컴퓨터가 진정한 GUID를 생성한다면, 약 1 초 내에 1 %의 확률로 1 %의 확률로 충돌을 일으킬 것입니다. 따라서 데이터베이스 ID에 GUID를 사용하는 경우 고유합니다. 지구상에서 수행되는 모든 계산에 대한 GUID는 즉시 충돌합니다.
thesaint

11
'아니요'라고 말할 수 없으며 특정 금액이 생성 될 때 충돌이 발생할 확률이 1 %라는 것은 직접 충돌입니다. 정답은 이론적으로되어야합니다.-충돌은 무작위로 발생할 수 있습니다. 그러나 충돌 가능성은 지구를 때리는 소행성보다 통계적으로 더 작으며, 지구에서 튀어 나와 다음 달에 두 번째로 지구를 때리기 위해 달에서 반동합니다.
Baaleos

112

기본적으로 그들은 불가능합니다! 천문학적으로 가능성은 낮다 .

하지만 ... 나는 내가 알고있는 세계에서 유일하게 GUID가 한 번만있는 사람 입니다.

그리고 나는 그것을 확신하고 실수가 아니라고 확신합니다.

Pocket PC에서 실행되는 작은 응용 프로그램에서는 작업이 끝날 때 GUID가 생성 된 명령을 실행해야했습니다. 서버에서 실행 된 명령은 실행 날짜와 함께 서버의 명령 테이블에 저장되었습니다. 어느 날 디버깅 할 때 모듈 명령 (새로 생성 된 GUID가 첨부 된)을 발행했지만 아무 일도 일어나지 않았습니다. 작업을 시작할 때 guid가 한 번만 생성되었으므로 동일한 guid로 다시 수행했으며 명령이 실행되지 않는 이유를 찾으려고 아무것도하지 않았습니다. 명령 테이블을 확인했습니다. 현재 GUID와 동일한 GUID가 3 주 전에 삽입되었습니다. 이것을 믿지 않고 2 주 백업에서 데이터베이스를 복원했으며 guid가있었습니다. 코드를 확인하면 새로운 guid가 의심의 여지없이 새로 생성되었습니다.

편집 :이 발생 가능성을 크게 높일 수있는 몇 가지 요소가 있으며 응용 프로그램이 PocketPC 에뮬레이터에서 실행 중이며 에뮬레이터에 상태 저장 기능이있어 상태가 복원 될 때마다 현지 시간도 복원됩니다. guid는 내부 타이머를 기반으로합니다 .... 또한 컴팩트 프레임 워크를위한 guid 생성 알고리즘은 COM보다 덜 완벽 할 수 있습니다.


38
공감. 상태 저장 및 재생은 실제로 중복 guid를 생성합니다.
Joshua

35
아마도 이것이 "나쁜"GUID 구현이었을 것입니다. 이론적 확률은 매우 낮은했지만, 포켓 PC에 ?? 누가 그런 가능성을 "아마도 가능하지는 않지만"범주에 부딪히는 지름길을 취하지 않았다고 누가 말할 것입니다.
Dave Dopson

9
어떤 일이 일어날 확률이 매우 낮다고해서 그런 일이 일어나지 않을 것이라는 의미는 아닙니다.
Renan

3
위에서 말했듯이 그 가능성은 점점 작아 져서 실수를했거나 MSSQL이 결함이있는 PRNG ( en.wikipedia.org/wiki/Pseudorandom_number_generator )를 사용한다고 가정하는 것이 안전합니다 . 예를 들어이 PRNG는 작은 크기의 씨앗으로 초기화 될 수 있습니다. 결함이 PRNG도가 (참조 드문되지 않습니다 schneier.com/paper-prngs.html를 ) - 예를 들어 하나의 결함은 최근 안드로이드 SDK에서 발견되었다 - android-developers.blogspot.com/2013/08/... + usenix.org/conference/woot14 / workshop-program / presentation /…
Alex

2
@Alex의 실수는 에뮬레이터의 "상태 저장 및 복원"으로, 에뮬레이터 시계를 포함한 전체 에뮬레이터 이미지를 복원합니다. 따라서 1 년에 걸쳐 수천 건의 복원 작업 후 하나의 guid 충돌이 발생했습니다. 당신은 바로 실수가 있었다!
팝 카탈린

34

그것들은 이론적으로는 가능하지만 3.4E38의 가능한 숫자로 1 년에 수십 조의 GUID를 생성하면 한 번의 복제 가능성은 0.00000000006 ( Source )입니다.

두 명의 사용자가 동일한 GUID를 사용하면 프로그램에 데이터가 복사되거나 공유되는 버그가 있다고 생각합니다.


"하지만 3.4E38 가능한 숫자로"-아니. 동일한 머신에서 거의 동시에 생성 된 두 개의 GUID는 매우 유사한 GUID로 끝납니다.
Kirk Strauser

4
그것은 GUID가 어떻게 생성되는지에 달려 있으며 CPU 시간 또는 밀리 초를 기반으로 한 일부 구현은 밀리 초 단위로 생성 된 두 개의 GUID를 기반으로 계산을 계산하면 큰 차이가 있습니다.
Dalin Seivewright

4
기계에 프로세서가 두 개 이상인 경우 guid가 시간 및 mac 주소를 기반으로하는 경우 각 코어는 같은 순간에 동일한 guid를 발행 할 수 있습니다.
AndyM

12
나는 괜찮은 GUID 구현이되지 않을 것이라고 확신한다
Guillaume86

1
@MatthewLock 생일 역설은 소스에서 다룹니다. 링크를 확인하십시오.
Zero3

21

먼저 두 GUID의 충돌 가능성을 살펴 보겠습니다. 다른 답변에서 언급했듯이 생일 역설 때문에 2 ^ 128 (10 ^ 38)의 1은 아닙니다. 즉, 두 GUID가 충돌 할 확률이 2 ^ 64 (10 ^ 19) 이것은 훨씬 작습니다. 그러나 이것은 여전히 ​​매우 많으며 합리적인 수의 GUID를 사용한다고 가정 할 때 충돌 확률이 낮습니다.

또한 많은 사람들이 생각하는 것처럼 GUID에는 타임 스탬프 또는 MAC 주소가 포함되어 있지 않습니다. 이것은 v1 GUID에 해당되었지만 이제는 의사 난수 인 v4 GUID가 사용되는데, 이는 더 이상 시간과 기계에 고유하지 않기 때문에 충돌 가능성이 더 높음을 의미합니다.

따라서 본질적으로 대답은 그렇습니다. 충돌이 가능합니다. 그러나 그들은 가능성이 거의 없습니다.

편집 : 2 ^ 64로 고정


2
나는 당신의 모든 사실에 동의하지만, 당신의 수학에주의하십시오. 두 개의 GUID가 충돌 할 확률이 10 ^ 19 일 확률이 1이라고하면 세트에있는 GUID 수에 따라 다릅니다. 이 기회에 ~ 2 ^ 32 GUID가 필요하므로 거의 모든 실제 시나리오에서 확률이 훨씬 낮습니다.
DocMax

1
당신은 오타 1 in 10^64 (10^19)가 있습니다 1 in 2^64 (10^19). 나는 생일 역설이 단지 2 개의 숫자에 어떻게 적용된다고 생각하는지 매우 혼란 스럽습니다. 나는 당신이 en.wikipedia.org/wiki/Birthday_paradox본다고 가정합니다 . 이 표는 주어진 복제 확률에 필요한 guid 수를 보여줍니다. 이 표에서 10 ^ 18의 1 확률은 단지 두 GUID에 가까운 것이 아니라 2.6 * 10 ^ 10 guid를 필요로합니다.
Tony Lee

한 가지 요점-v1 guid는 여전히 널리 사용되고 있으며 특히 바람직한 특성을 가진 데이터베이스에서 MAC 주소에 의존합니다. UuidCreateSequential 및 SQL Server 래퍼 NewSequentialID ( msdn.microsoft.com/en-us/library/windows/desktop/… )를 참조하십시오 .
EBarr

18

두 개의 임의 GUID 충돌 가능성 (10 ^ 38에서 ~ 1)은 손상된 TCP / IP 패킷을 감지하지 못할 확률보다 낮습니다 (10 ^ 10에서 ~ 1). http://wwwse.inf.tu-dresden.de/data/courses/SE1/SE1-2004-lec12.pdf , 11 페이지 이것은 디스크 드라이브, CD 드라이브 등에도 적용됩니다.

GUID는 통계적으로 고유하며 db에서 읽은 데이터는 통계적으로 만 정확합니다.


10 ^ 28 패킷 중 1보다 작은 패킷이 손상되어 네트워크를 보호 할 수 없습니까?
Joshua

13

나는 고려할 것 오캄의 면도날 이 경우에 좋은 가이드로. GUID 충돌이 발생할 가능성은 거의 없습니다. 버그가 있거나 데이터를 엉망으로 만드는 사람이 훨씬 많습니다.


1
실제로이 상황에서 Occam의 면도기는 전혀 좋은 가이드가 아닙니다! Occam의 면도기는 가정이 가장 적은 경우가 가장 정확하다고 말합니다. 이 상황에서 GUID 충돌의 경우는 실제로 훨씬 간단하지만 Occam의 면도기는 이러한 경우 중 하나가 믿을 수 없을 것임을 이미 알고있는 상황에는 적용되지 않습니다.
lockstock

11

Wikipedia의 글로벌 고유 식별자 (Globally Unique Identifier) 기사를 참조하십시오. GUID를 생성하는 방법에는 여러 가지가 있습니다. 분명히 오래된 (?) 방식은 Mac 주소, 매우 짧은 단위의 타임 스탬프 및 고유 한 카운터 (동일한 컴퓨터에서 빠른 세대를 관리하기 위해)를 사용했기 때문에 복제하는 것은 거의 불가능합니다. 그러나이 GUID는 사용자를 추적하는 데 사용될 수 있기 때문에 삭제되었습니다 ...

Microsoft에서 사용하는 새로운 알고리즘에 대해 잘 모르겠습니다 (이 기사에서는 GUID 시퀀스를 예측할 수 있다고 말하지만 더 이상 타임 스탬프를 사용하지 않는 것 같습니다. 위에 링크 된 Microsoft 기사에 다른 내용이 나와 있습니다 ...).

이제 GUID는 이름이 전 세계적으로 고유하도록 신중하게 설계되었으므로 불가능하거나 매우 낮은 확률로 위험에 처할 것입니다. 나는 다른 곳을 볼 것이다.





9

MAC 주소가 중복 된 이더넷 카드가있는 두 대의 Win95 시스템은 엄격하게 제어 된 조건에서 특히 GUI (예 : 건물의 전원이 꺼지고 정확히 동시에 부팅되는 경우)에서 중복 GUIDS를 발행합니다.


서로 다른 두 시스템이 동일한 이더넷 MAC 주소를 갖는 것이 일반적입니까?
Dave Lucre

@DaveLucre : 아니요. 그러나 사건이 기록되었습니다.
Joshua

나는 이것이 어떻게 일어나는지 정말로 궁금합니다. 각 NIC에 대해 임의로 MAC을 생성하는 VM에서 더 가능성이 높습니까? 물리적 NIC가 중복 MAC로 제조되고 있다고 들어 본 적이 없습니다! 가능하다면 작품에 엄청난 스패너를 던졌습니다!
Dave Lucre 2016 년

와! 링크 @Joshua에 감사드립니다! 정말 대단한 일이야!
Dave Lucre

@DaveLucre 필자는 매우 저렴한 USB NIC를 사용했는데 모두 동일한 MAC로 제조되었습니다. 그러나 물론 그것은 임의성 수학과는 관련이 없으며 제조업체의 게으름과 관련이 있습니다.
rudolfbyker

5

나는 "나는 네트워킹 사람이 아니기 때문에 다음과 같이 완전히 일관되지 않은 문장을 만들 수있다."라는 제목을 붙일 것이다.

일리노이 주립 대학에서 일할 때, 서로 다른 시간에 주문 된 두 개의 Dell 데스크탑이있었습니다. 첫 번째는 네트워크에 배치했지만 두 번째는 네트워크에 배치하려고 시도 할 때 심각한 오류가 발생하기 시작했습니다. 많은 문제 해결 후 두 시스템에서 동일한 GUID를 생성하는 것으로 확인되었습니다 (정확히 무엇을 알지 못하지만 네트워크에서 모두 사용할 수 없게 만들었습니다). 실제로 Dell은 두 시스템을 모두 결함이있는 것으로 교체했습니다.


3
구체적으로 GUID였습니다. 컴퓨터가 네트워크에 가입했을 때 생성 된 GUID와 관련이있었습니다. GUID가 동일하지 않다고 말했기 때문에 Dell이 시스템을 교체하는 데 몇 주가 걸렸습니다. 우리는 문제를 재현 할 수 있었고 Dell은 기계를 다시 가져와 네트워크에서 동일한 결과를 얻을 수있었습니다. 결국 두 기계를 교체하게되었습니다. 내가 말했듯이, 나는 네트워킹 사람이 아니지만 GUID에 문제가 있음을 기억합니다.
John Kraft

5

GUID가 마술적이고 독창적이라고 보장되는 기분이 좋은 대답을 알고 있지만 실제로 대부분의 GUID는 121 비트의 난수 (7 비트는 형식화에 낭비 됨)입니다. 큰 난수를 사용하는 것이 편하지 않다면 GUID를 사용하는 것이 불편하지 않아야합니다.


11
또한 네트워크를 사용하지 않는 것이 좋습니다. 또는 컴퓨터. 패리티 비트는 너무 많이 할 수 있습니다!
Rushyo

당신은 오해했다. 이 게시물에서 내가 말하려고했던 두 가지가 있습니다 : 1) 큰 임의의 숫자가 필요한 경우 큰 임의의 숫자를 사용하십시오. GUID를 큰 난수로 사용하는 것은 불필요하게 오해의 소지가 있습니다. (2)
Rick Yorgason 21

4
내가 완전히 알고있는 "큰 난수를 사용하는 것이 편하지 않다면" 그러나 GUID는 매우 독특하여 컴퓨터의 다른 모든 것이 훨씬 임의적이며 심지어 당연한 작업조차도 찾을 수 있습니다. 괴물 메모리 결함이 (진정한) GUID 충돌이 발생하는 것보다 신원 열을 깨뜨릴 가능성이 더 큽니다. 당신은 그들에 대해 '불편'하다고 생각해서는 안됩니다. 시나리오에 이상적이지 않으면 괜찮지 만 특별한주의가 필요하지 않습니다.
Rushyo

3
나는 이것이 아무데도 가고 있지 않다고 생각하지만 사람들이 당신에게 설명하려고하는 것은 네트워크 카드 또는 하드 드라이브와 같은 일반적인 하드웨어의 오류 감지 메커니즘이 GUID 충돌을 일으키는 것보다 오류를 감지하지 못할 가능성이 큰 알고리즘을 사용한다는 것입니다. 당신은 이것에 의존하고, 당신은 또한 GUID에 의존 할 수 있습니다
Guillaume86

1
@Rick은 숫자가 얼마나 큰지에 달려 있습니다. 확실히 4 바이트 int 또는 8 바이트 bigint는 아닙니다. GUID = 16 바이트이므로 동일한 2 ^ 128 가능한 조합을 달성하기 위해 사용자 지정 16 바이트 큰 숫자 구현이 필요합니다. 따라서 일반적으로 '정상적인'int 또는 bigint 난수를 사용하는 경우 GUID와의 충돌 가능성 더 낮습니다 (각각에 대해 임의의 알고리즘 고려 사항은 제외).
Wim Hollebrandse

3

GUID를 생성하는 데 사용 된 코드에 버그가있을 수 있습니까? 물론 가능합니다. 그러나 대답은 컴파일러 버그와 동일합니다. 자신의 코드는 버그가 많을 가능성이 높으므로 먼저 살펴보십시오.


2

물론 가능합니다. 가능성은 없지만 가능합니다.

동일한 머신이 모든 GUID (서버)를 생성하므로 머신 특정 정보를 기반으로하는 많은 "임의성"이 손실됩니다.


1

grins을 위해 다음 스크립트를 사용해보십시오 ... (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 초 미만 소요) 매우 짧은 시간 간격이 있어도 첫 번째 선택에서 상당히 넓은 범위가 생성됩니다. 지금까지 두 번째 선택은 아무것도 생성하지 않았습니다.


1
카운터 끝에서 50 %의 확률로 중복이 발생하도록 15 개의 제로가 더 필요합니다. 그러나 피트를 위해서하지 마십시오!
Jim Birchall

0

사용자에게 네트워크 카드가있는 다른 시스템이있는 경우에는 불가능하지만 여전히 거의 이론적 인 위험이 아닙니다.

개인적으로 나는 GUID 충돌보다는 버그 일 가능성이 더 높은 다른 곳을보고 싶습니다 ...

물론 GUID를 더 짧게 만들기 위해 비트를 잘라 내지 않습니다.


GUID는 서버에서 생성되므로 사용자의 네트워크 카드가 작동하지 않습니다.
Tom Ritter

0

물론 가능하고 가능할 수도 있습니다. 각 GUID가 가능한 숫자 공간의 임의 부분에있는 것은 아닙니다. 두 개의 스레드가 하나를 동시에 생성하려고 시도 할 때 세마포어가있는 중앙 집중식 GUID 기능을 사용하지 않으면 동일한 값으로 끝날 수 있습니다.


0

GUID 충돌을 다음과 같은 방법으로 생성하는 경우 GUID 충돌이 발생할 가능성이 거의 없습니다. NEWID()SQL Server 함수 기능을 (물론 다른 대답이 강조했듯이 가능할 수도 있음). 그들이 지적하지 않은 한 가지는 실제로 브라우저에서 JavaScript로 GUID를 생성하는 경우 실제로 충돌이 발생할 가능성이 높다는 것입니다. 다른 브라우저의 RNG에 문제가있을뿐만 아니라 Google 스파이더가 그러한 기능의 결과를 캐시하는 것처럼 보이는 문제가 발생하여 동일한 GUID를 시스템에 반복적으로 전달합니다.

자세한 내용은 여기에서 다양한 답변을 참조하십시오.

JavaScript에서 UUID를 생성 할 때 충돌이 발생합니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.