UUID 충돌 [폐쇄]


33

우리가 사용하는 난수 생성기가 실제로 무작위가 아니며 동일한 코드를 실행하는 수십 또는 수백 개의 동일한 기계가있을 수 있다는 점을 감안할 때, 특히 버전 4 (임의) UUID에서 UUID 충돌 가능성에 대한 실제 연구를 한 사람이 있습니까? UUID 생성?

동료들은 UUID 충돌 테스트를 완전히 시간 낭비라고 생각하지만 항상 데이터베이스에서 중복 키 예외를 포착하고 새로운 UUID로 다시 시도하도록 코드를 작성했습니다. 그러나 UUID가 다른 프로세스에서 왔고 실제 객체를 참조하면 문제가 해결되지 않습니다.


4
이 질문은 기본 Google 검색을 보여주는 것처럼 Stack Overflow : stackoverflow.com/questions/3038023/… 에 이미 답변되었습니다 . google.com/search?q=uuid+collision
Arseni Mourzenko

3
이 질문은 SQL * Server에서 사용되는 특정 알고리즘에 관한 것으로, 버전 4 (임의)가 아닙니다. 특히 버전 4에 대해 묻고 있습니다.
Paul Tomblin

NEWID()함수 의 SQL Server 구현이 무작위가 아니라고 말하는가 ? 그렇다면 그러한 주장을 뒷받침 할만한 자료가 있습니까? 출력은 분명히 v4 UUID와 같습니다. NEWSEQUENTIALID()완전히 무작위적인 것은 아니지만, 그 목적입니다 . 최소한 UUID가 인덱스 키로 잘 작동하는 UUID를 생성하는 것입니다.
CVn

1
NEWID ()에 mac 주소의 일부 비트가 포함되어있어 V4가 아닌 V1 또는 V2 UUID가된다는 링크 된 질문에 대한 답변을 드리겠습니다.
Paul Tomblin 2012 년

2
이 책에서 특히에 StackOverflow에, 이미 인터넷에 광고 nauseum 논의 것에 대해 있기 때문에이 질문은 주제 꺼져있는 것처럼 보이

답변:


18

Wikipedia에는 ​​몇 가지 세부 정보가 있습니다.

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 random generator http://xkcd.com/221/ 에서 quantum noise를 사용하는 하드웨어 장치에 이르기까지 거의 모든 것을 허용 합니다. RFC의 보안 고려 사항 :

"6. 다양한 호스트에서 UUID를 생성하는 분산 응용 프로그램은 모든 호스트에서 난수 소스를 기꺼이 사용해야합니다. 이것이 불가능한 경우 네임 스페이스 변형을 사용해야합니다."

나는 이것을 다음과 같이 읽었습니다. 당신은 스스로 있습니다. 자신의 응용 프로그램 내에서 임의의 생성기를 담당하지만 이것과 다른 것은 신뢰를 기반으로합니다. 선택한 랜덤 생성기를 올바르게 이해하고 사용하는 자신의 능력을 신뢰하지 않는다면 실제로 충돌을 확인하는 것이 좋습니다. 다른 프로세스의 프로그래머를 신뢰하지 않으면 충돌을 확인하거나 다른 UUID 버전을 사용하십시오.


11

충돌이 발생했는지 확실하게 감지해야하며 충돌이 발생하면 응용 프로그램에서 예외가 발생해야합니다. 예를 들어 UUID를 데이터베이스에서 기본 키로 사용하는 경우 충돌 ID를 삽입 할 때 데이터베이스에서 오류가 발생합니다.

그러나 충돌의 경우 새 UUID를 생성하고 다시 시간 낭비가되는 코드를 작성한다고 생각합니다. 충돌이 발생할 가능성이 너무 작아서 예외를 던지는 것이이를 처리하는 데 합당한 방법이 될 것입니다.

코드를 작성하는 데 시간을 낭비 할뿐만 아니라 코드를 더 복잡하게하여 다음 사람이 읽기 어려워 거의 이득을 얻지 못한다는 것을 기억하십시오.


2
UUID는 랜덤 생성기만큼 좋습니다. 매우 ( 매우 ) 열악한 충돌로 하나의 충돌이 발생할뿐만 아니라 불가피합니다. 그것은 아마도 세대에 복제본을 확인하는 것은 실제로 과잉 일 것이지만, 상황이 발생할 수 있고 내 생각으로는 그렇게 많이 요구하지 않을 것이라고 기대했습니다. 일부 도메인 (예 : 건강 관리)에서는 그러한 상황을 포착하는 코드 (아마도 데이터베이스의 충돌 감지)가 필요하다고 생각합니다. 결코 일어나지 않는 상황을 디버깅하는 데 얼마나 많은 시간을 소비했는지 놀랄 것입니다.
Newtopian 2019 년

1
나는 내가 자신을 명확하게하지 않았다고 생각합니다. 더 명확하게 답변을 업데이트했습니다.
Pete

7

이것은 매우 좋은 질문입니다. 나는 어디에서나 UUID를 사용하기 위해 서두르는 것이 적절하다고 생각하지 않습니다. 나는 확실한 연구를 찾지 못했습니다.

제안 : 여기에 매우주의하여 암호화를 잘 알고 있어야합니다. 128 비트 UUID를 사용하는 경우 '생일 효과'는 각 키에 128 비트의 엔트로피가있는 경우 약 2 ^ 64 개의 키를 생성 한 후 충돌이 발생했음을 나타냅니다 .

실제로 이것이 사실인지 확인하기는 다소 어렵습니다. (a) 방사성 붕괴 (b) 랜덤 배경 무선 노이즈에서 진정한 임의성을 생성 할 수 있습니다. 예를 들어 역 바이어스 된 제너 다이오드에서 취한 적절한 전자 노이즈를 신중하게 선택하지 않는 한 종종 오염됩니다. (나는 마지막으로 연주했으며 매력처럼 작동합니다. BTW).

사용자가 2 ^ 64 (예 : 약 10 ^ 19) 키에 접근하는 것을 생성하지 않고 서로 확인한 경우를 제외하고는 "1 년 동안 사용하지 않았 음"과 같은 선언을 신뢰하지 않습니다. 사소한 운동.

문제는 이것입니다. 다른 모든 사람이 공통 키 공간에서 생성하는 다른 모든 키와 키를 비교할 때 100 비트의 엔트로피가 있다고 가정 해 봅시다. 약 2 ^ 50에서 충돌이 시작됩니다. 약 10 ^ 15 키. 1000 억 개의 키로 데이터베이스를 채운 경우 충돌이 발생할 가능성은 여전히 ​​미미합니다. 확인하지 않으면 나중에 peta-row 크기의 데이터베이스에 발생하는 예기치 않은 오류가 발생합니다. 이것은 물린 수 있습니다.

이러한 UUID를 생성하는 데 여러 가지 접근 방식이 있다는 사실은 순간적인 경련의 원인이됩니다. 유형 4 UUID에 대해 충분한 엔트로피를 가진 '정확한 무작위'프로세스를 사용하는 생성기가 거의 없다는 것을 알고있을 때 생성기 의 엔트로피 내용을주의 깊게 검사 하지 않으면 지나치게 걱정해야합니다 . (대부분의 사람들은이 작업을 수행하지 않거나 방법을 알지 못합니다. DieHarder 제품군으로 시작할 수도 있습니다). 의사 난수 생성과 실제 난수 생성을 혼동하지 마십시오.

입력 한 엔트로피가 자신이 갖고있는 엔트로피임을 알고 있어야하며 암호화 기능을 적용하여 키를 교란 시키면 엔트로피가 변경되지 않습니다. 전체 공간이 숫자 0과 1을 포함하는 경우 엔트로피 내용이 다음 두 문자열의 내용과 동일하다는 것이 명백하지 않을 수 있습니다. ! @@ # & ^ % $$) ,. m} "및"완전히 다른 것을위한 지금 ". 여전히 두 가지 옵션이 있습니다.

무작위성은 제대로하기가 까다 롭지 않으며 단순히 "전문가들이 그것을 보았으므로 괜찮습니다"라고 믿으면 충분하지 않습니다. 전문가 암호 전문가 (그리고 실제로 능숙한 사람은 거의 없습니다)는 종종 잘못 알고 있다고 인정합니다. 우리는 heartbleed, DigiNotar 등을 믿었습니다.

폴 툼 린이 적절한주의를 기울이고 있다고 생각합니다. 내 2c.


6

당신이 가진 문제는 "랜덤 번호 생성기"를 사용하고 해당 생성기가 얼마나 무작위인지 모르는 경우 실제로 충돌 확률을 알 수 없다는 것입니다. 난수 생성기가 어떤 방식으로 상관되는 경우 충돌 가능성이 크게 증가 할 수 있습니다.

충돌 확률이 매우 작더라도 근본적인 문제가 있습니다. 확률이 0이 아닙니다. 이는 충돌이 결국 발생한다는 것을 의미하며, 자주 발생하지는 않습니다.

UUID를 자주 생성하고 사용하면 충돌이 더 빨리 나타납니다. (1 년에 1을 생성한다는 것은 초당 백만을 생성하는 것보다 대기 시간이 더 길다는 것을 의미합니다.

해당 확률이 유한하고 알려지지 않았으며 많은 UUID를 사용하는 경우 충돌의 결과를 고려해야합니다. 예외를 던져서 비즈니스 응용 프로그램을 종료하는 것이 허용되지 않으면 그렇게하지 마십시오! (제 머리 위의 예 : "라이브러리 체크인을 업데이트하는 동안 웹 서버를 종료해도 괜찮습니다. 자주 발생하지는 않습니다."및 "중간에 급여 시스템을 종료해도됩니다. 이러한 결정은 경력 제한 조치 일 수 있습니다.)

그래도 응용 프로그램에 따라 더 나쁜 경우가있을 수 있습니다. UUID의 존재를 테스트 한 후 (즉, 조회 수행) 이미 존재하지 않는 경우 새로 작성하는 경우 (일반적으로 수행해야 할 일반적인 작업) 레코드를 연결하거나 관계를 맺고 있음을 발견 할 수 있습니다 실제로 UUID를 통해 연결해서는 안되는 두 가지를 연결하는 경우. 이것은 예외를 던지면 아무것도 해결되지 않으며 어딘가에 감지 할 수없는 혼란이 있습니다. 이것은 정보 유출로 이어지고 매우 창피한 일입니다. (예 : 은행에 로그인하여 다른 사람의 계좌 잔액을 볼 수 있음을 알 수 있습니다! 나쁨!)

요약 : UUID 사용 방식과 충돌의 결과를 고려해야합니다. 충돌 감지 및 회피, 충돌시 간단한 조치 수행 또는 조치를 취해야하는지 여부를 결정합니다. 어떤 상황에서는 단순하고 한 번에 맞는 솔루션이 적합하지 않을 수 있습니다.


2
"충돌의 확률은 0이 아닙니다" 모든 유한 길이 시퀀스에는이 속성이 있습니다. 심지어와 완벽하게 당신이 2 ^ (122) 고유의 UUID (128 비트 마이너스 4 비트 버전을 뺀 2 예약 비트)를 생성 한 후 임의 V4의 UUID, 당신이 생성 다음 하나가되어 보장 충돌 할 수 있습니다. 아마도 그보다 빨리 충돌을 일으킬 것입니다. 더 큰 문제는 5e36 반복과 같은 충돌 이후의 문제가 문제인지 여부 이며, 요약에서 말한 것처럼 일반적으로 (각 특정 경우에 대답 할 수는 있지만) 대답 할 수 없습니다 .
CVn

당연하지. 이것은 명백한 진술입니다 (그러나 여전히 반복됩니다). 문제는 난수 생성기와 얼마나 많은 상관 관계가 있는지입니다. 이것은 충돌 확률을 크게 증가시킬 수 있지만 (2 ^ large), 파기, 연구 또는 계산을 많이 하지 않으면 알 수없는 것 입니다. 충돌 가능성이 가장 좋은 값보다 훨씬 나쁘다고 가정하면 아마 신중해야합니다. 그 후 ... 결과를 고려해야합니다.
quick_now

0

관련된 두 가지 문제가 있습니다.

  1. 사용되는 난수 생성기의 품질입니다.

  2. 생성 될 수있는 UUID의 양입니다.

"무작위"UUID에는 122 개의 임의 비트가 있습니다. 완벽한 임의성을 가정하면 약 2 ^ 61 개의 생성 된 UUID (2 ^ 122의 제곱근)에서 첫 번째 충돌을 예상 할 수 있습니다. 이 지구상의 모든 사람이 초당 UUID를 생성하는 경우 연간 10,000,000,000 * 365 * 24 * 60 = 60 = 315360000000000000 UUID이며 이는 2 ^ 58에 매우 가깝습니다. 즉, 몇 년 후에 첫 번째 충돌이 발생합니다. 응용 프로그램이 해당 숫자 근처에 있지 않으면 랜덤 생성기의 품질이 괜찮다면 충돌이 발생하지 않을 것입니다.

난수 생성기에 대해 이야기하기 : 표준 C 라이브러리 생성기 (직접, 간접 또는 유사한 생성기)를 사용하는 경우 아마도 시간과 함께 시드 할 수 있습니다. 충돌을 피하기에 충분한 엔트로피를 그릴 수 없습니다. 그러나 Linux를 사용하는 경우 16 바이트의 데이터를 읽으십시오 /dev/urandom. 이것은 실제 임의의 이벤트에 액세스 할 수있는 커널에 의해 흔들리는 엔트로피 풀을 그립니다. 일반적으로 UUID를 실제로 생성하지 않는 한 부팅 시퀀스 초기에 실제로 /dev/urandom임의의 소스처럼 동작해야합니다.


-1

나는 1000 만 UUID-s를 생성하는 아주 간단한 (브 루트 포스) 프로그램을 사용하여 한 번 테스트했으며 충돌을 경험하지 않았습니다.

UUID RFC는 UUID를가 (의사) 난수 단지 무리 아니라고 말한다.


1
내가 묻고있는 버전 4는 거의 모든 6 비트를 제외하고는 임의의 숫자입니다.
Paul Tomblin

8
1 천만 달러는 버킷에서 떨어지지 않습니다. 충돌 가능성은 3E30의 1에 불과합니다. 당신이 하나를 발견하면, 나는 당신이 당신이 할 수있는 모든 복권마다 서둘러 티켓을 구입하는 것이 좋습니다!
로스 패터슨

@RossPatterson, 내가 특별히 궁금한 점은 동일한 하드웨어에서 똑같은 유사 난수 알고리즘을 사용하여 수백 대의 컴퓨터가 충돌 가능성을 크게 증가 시킨다는 것입니다. 나는 그것을 의심합니다.
Paul Tomblin

1
@Paul-초기 시딩 프로세스에 엔트로피가 충분하지 않은 경우에만 생각했습니다. 시딩이 약하다는 것은 의심의 여지가 있습니다. 하드웨어 일련 번호가 사용될 수도 있습니다. 물론 각 기계마다 고유 할 것입니다.
Steve314

1
아아, 파종은 매우 약할 수 있습니다. Linux 시스템은 매우 임의의 소스 (장치 드라이버 활동 ) 에서 PRNG를 시드하는 것을 좋아 하지만, 다른 환경에서는 표준 시간 동기화에 충분한 기계가있는 문제가 될 수있는 현재 타임 스탬프를 사용하는 것이 표준입니다.
로스 패터슨
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.