GUID가 고유하지 않다는 간단한 증거


323

간단한 테스트 프로그램에서 GUID가 고유하지 않다는 것을 증명하고 싶습니다. 다음 코드가 몇 시간 동안 실행될 것으로 예상했지만 작동하지 않습니다. 어떻게 작동시킬 수 있습니까?

BigInteger begin = new BigInteger((long)0);
BigInteger end = new BigInteger("340282366920938463463374607431768211456",10);  //2^128
for(begin; begin<end; begin++)
  Console.WriteLine(System.Guid.NewGuid().ToString());

C #을 사용하고 있습니다.


107
소프트웨어 개발자로서 사용자가 와서 "작동하지 않는다"고 말하면 어떻게 하시겠습니까?
JoshJordan 2009

152
몇 조를 기다려라.
hobbs November

67
이것이 내가 온라인에서 본 가장 재미있는 것이므로 업데이트되었습니다.
jrockway

32
@jrockway-lol. 근본적으로 잘못되지 않은이 질문에 대한 문제를 찾는 데 어려움을 겪고 있습니다. 내가 더 오래 볼수록 더 재미있어집니다.
tylerl

243
전 세계적으로 유일하기 때문에 지구상에서만 유일합니다. 진정으로 고유 한 ID를 원하면 UUID ( Universally Unique ID) 를 사용해야합니다 . 나는 당신이 우리 우주 안에서의 독창성에만 관심이 있다고 가정합니다. :-)
tvanfosson

답변:


407

Kai, 스레드를 사용하여 원하는 작업을 수행하는 프로그램을 제공했습니다. 다음 조건에 따라 라이센스가 부여됩니다. 실행하는 CPU 코어 당 시간당 $ 0.0001을 지불해야합니다. 매월 말에 요금을 지불해야합니다. 빠른 시일 내에 저의 페이팔 계정 정보를 원하시면 저에게 연락하십시오.

using System;
using System.Collections.Generic;
using System.Linq;

namespace GuidCollisionDetector
{
    class Program
    {
        static void Main(string[] args)
        {
            //var reserveSomeRam = new byte[1024 * 1024 * 100];     // This indeed has no effect.

            Console.WriteLine("{0:u} - Building a bigHeapOGuids.", DateTime.Now);
            // Fill up memory with guids.
            var bigHeapOGuids = new HashSet<Guid>();
            try
            {
                do
                {
                    bigHeapOGuids.Add(Guid.NewGuid());
                } while (true);
            }
            catch (OutOfMemoryException)
            {
                // Release the ram we allocated up front.
                // Actually, these are pointless too.
                //GC.KeepAlive(reserveSomeRam);
                //GC.Collect();
            }
            Console.WriteLine("{0:u} - Built bigHeapOGuids, contains {1} of them.", DateTime.Now, bigHeapOGuids.LongCount());


            // Spool up some threads to keep checking if there's a match.
            // Keep running until the heat death of the universe.
            for (long k = 0; k < Int64.MaxValue; k++)
            {
                for (long j = 0; j < Int64.MaxValue; j++)
                {
                    Console.WriteLine("{0:u} - Looking for collisions with {1} thread(s)....", DateTime.Now, Environment.ProcessorCount);
                    System.Threading.Tasks.Parallel.For(0, Int32.MaxValue, (i) =>
                    {
                        if (bigHeapOGuids.Contains(Guid.NewGuid()))
                            throw new ApplicationException("Guids collided! Oh my gosh!");
                    }
                    );
                    Console.WriteLine("{0:u} - That was another {1} attempts without a collision.", DateTime.Now, ((long)Int32.MaxValue) * Environment.ProcessorCount);
                }
            }
            Console.WriteLine("Umm... why hasn't the universe ended yet?");
        }
    }
}

추신 : 병렬 확장 라이브러리를 사용 해보고 싶었습니다. 그것은 쉽다.

제어 흐름으로 OutOfMemoryException을 사용하면 느낌이 잘못됩니다.

편집하다

글쎄, 이것은 여전히 ​​투표를 유치하는 것 같습니다. 그래서 GC.KeepAlive () 문제를 해결했습니다. 그리고 C # 4로 실행되도록 변경했습니다.

또한 지원 조건을 명확히하기 위해 2010 년 2 월 28 일만 지원됩니다. 그날에만 지원 요청을하려면 타임머신을 사용하십시오.

편집 2 항상 그렇듯이 GC는 메모리 관리보다 더 나은 작업을 수행합니다. 직접 시도했던 모든 시도는 실패로 끝났습니다.


120
그 마지막 Console.WriteLine은 정말 웃기게 만들었습니다. 나는 당신이 CommonlyAcceptedCosmologicTheoriesWrongException대신 던져야한다고 생각합니다 .
R. Martinho Fernandes

17
이 항목을 허용됨으로 표시하면 @Kai가 @ligos에서 지정한 조건을 수락한다는 의미입니까?
kb.

3
설정 reserveSomeRam = null;은 실제로 아무것도 달성하지 못합니다.
DevinB

4
@devinb 설명 해주십시오? GC가 할 수 있도록 이전에 할당 된 바이트를 해제하는 것처럼 보입니다 Collect(). 왜 아무것도 달성하지 못합니까?
mythz

3
GuidCollisionDetector. 이름은 잠재력이 있습니다
Ufuk Hacıoğulları

226

이것은 몇 시간 이상 동안 실행될 것입니다. 그것이 1GHz에서 반복된다고 가정하면 (그것은 그것보다 훨씬 느리지 않을 것입니다), 그것은 10790283070806014188970 년 동안 실행될 것입니다. 우주보다 나이가 약 83 억 배나 더 깁니다.

가정 무어의 법칙은 은,이 프로그램을 실행 수백 년을 기다려야 빠른 시간 수십억하는 컴퓨터에서 실행하지에 많이 더 빨리 될 것이다 보유하고있다. 실제로 CPU 속도가 두 배 (약 18 개월)로 걸리는 것보다 실행 시간이 오래 걸리는 프로그램은 CPU 속도가 증가 할 때까지 기다렸다가 실행하기 전에 새 CPU를 구입하면 (작성하지 않는 한) 더 빨리 완료됩니다. 새 하드웨어에서 일시 중지했다가 다시 시작할 수 있습니다).


27
젠장-아마 guids를 생성하는 서버 스레드가 더 좋은 생각입니까?
Kai

107
쿼드 코어 프로세서의 스레드 4 개는 우주 시대의 200 억 배에 달할 것입니다. 따라서 그렇습니다.
rjmunro 2009

34
나는 이것이 트롤이라고 의심하지만, 그렇지 않을 가능성이 있습니다 : 스레드는 마법이 아닙니다. 하나의 스레드에서 초당 10 억 개의 작업을 수행 할 수있는 경우 10 개의 스레드로 이동하면 각 스레드가 자주 1/10로 실행됩니다. 각 스레드는 초당 100M 작업을 수행합니다. 초당 총 작업 수는 증가하지 않습니다. 초당 작업 수를 늘리는 방법은 더 많은 컴퓨터를 구입하는 것입니다. 10 억 대 이상의 컴퓨터를 구입했다고 가정 해보십시오. 이로 인해 문제는 10790283070806 년으로 단축되며 여전히 4 시간 이상이 소요됩니다.
Eric Lippert

10
rjmunro는 각 스레드가 별도의 코어에서 실행될 것이라고 가정합니다. 8 천 8 백만 개의 우주 / 4 개의 핵심은 실제로 대략 200 억 개의 우주와 같습니다. 인텔 주식을 구입할 시간입니다!
Dour High Arch

4
@Erik 8,800 억 개의 프로세서는 우주가 지금까지 존재했던 시간 동안 처리 할 수 ​​있음을 의미합니다. 그래서 그것만으로는 충분하지 않습니다.
rjmunro

170

GUID는 이론적으로 고유하지 않습니다. 증거는 다음과 같습니다.

  • GUID는 128 비트 숫자입니다.
  • 오래된 GUID를 재사용하지 않으면 2 ^ 128 + 1 이상의 GUID를 생성 할 수 없습니다

그러나 태양의 전체 전력 출력이이 작업을 수행하도록 지시 된 경우 완료되기 오래 전에 냉각 될 것입니다.

GUID는 여러 가지 다른 전술을 사용하여 생성 될 수 있으며,이 중 일부는 특정 시스템이 동일한 GUID를 두 번 생성하지 않도록 특별한 조치를 취합니다. 특정 알고리즘에서 충돌을 발견하면 GUID를 생성하는 특정 방법이 나쁘다는 것을 알 수 있지만 일반적으로 GUID에 대해서는 아무 것도 증명하지 못합니다.


44
구조에 비둘기 구멍 원리!
yfeldblum 4

22
태양이 차가 워진 댓글에 +1 암호화 키> 256 비트의 무의미성에 대한 흥미로운 의견이있었습니다. 가능한 모든 주요 값을 반복하려면 전체 우주가 보유하는 것보다 더 많은 에너지가 필요합니다. CPU에서 비트를 토글하려면 적은 양의 에너지가 필요합니다 (열을 발생시키는 것입니다). 2 ^ 227kg, 우리 태양은 2 ^ 101kg이므로 2 ^ 126 태양입니다!
Skizz

31
@Skizz : 이것은 무차별 대입 공격에만 해당됩니다. 암호화 체계가 "손상된"경우 이는 무차별 대입보다 적은 시간에 해결할 수 있지만 해결 시간은 키 크기에 비례합니다.
Steven Sudit

1
@StevenSudit (P == NP 제외) 비례 키 크기와 지수를
Ihar 묻어

1
@Orlangur 비트 단위로 측정 된 키 크기에 비례합니다.
Steven Sudit

137

물론 GUID가 충돌 할 수 있습니다. GUID는 128 비트이므로 2^128 + 1이를 생성 하고 비둘기 구멍 원리에 따라 충돌이 발생해야합니다.

그러나 GUID가 고유하다고 말할 때 실제로 의미하는 것은 키 공간이 너무 커서 실수로 동일한 GUID를 두 번 생성하는 것이 실제로 불가능하다는 것입니다 (GUID를 임의로 생성한다고 가정).

일련의 nGUID를 무작위로 생성하는 경우 , 최소한 하나의 충돌 가능성은 대략적인 것입니다 p(n) = 1 - exp(-n^2 / 2 * 2^128)(이것은 가능한 생일 수가 있는 생일 문제 입니다 2^128).

   n     p(n)
2^30 1.69e-21
2^40 1.77e-15
2^50 1.86e-10
2^60 1.95e-03

이 숫자를 구체적으로 만들려면 2^60 = 1.15e+18. 따라서 초당 10 억 개의 GUID를 생성하는 경우 2^60임의의 GUID 를 생성하는 데 36 년이 걸리며 충돌 가능성은 여전히 ​​큽니다 1.95e-03. 앞으로 36 년 동안 충돌을 발견하는 것보다 인생의 어느 시점 ( 4.76e-03) 에서 살해 될 가능성이 높습니다 . 행운을 빕니다.


239
당신이 당신의 인생의 어느 시점에서 살 해당했다면, 그 가능성은 끝날 것입니다.
Michael Myers

25
@mmyers : 훌륭한 지적. 이것은 내 인생의 끝이 아니기 때문에 지금 당장 살해 당할 가능성이 낮다는 것을 의미합니다. 아, 잠깐만 ...
Steven Sudit

또한 짧은 기간 내에 두 개의 GUID가 생성되면 동일한 시스템 내에서 GUID를 사용할 가능성이 적습니다. 따라서 이것은 고유성을 증가시킵니다.
AMissico

이 숫자와 생일 문제에 대한 언급은 의미가 없습니다. GUID 생성 알고리즘은 전체 범위에서 동일한 확률로 값을 생성하지 않습니다. 실제로 IIRC의 원래 알고리즘은 생성 PC의 MAC 주소 + 결과의 일부로 현재 시간을 사용하여 다른 PC에서 생성 된 Guid와의 충돌 위험을 줄이지 만 물론 키 공간을 줄입니다.
Joe

17
당신은 살해 될 확률이 모든 인간에게 일정하다고 가정합니다. 그러나 포럼 게시물에 snide 발언을 쓰는 사람들은 보통 사람들보다 살해 될 가능성이 높은 사람들입니다.
Jay

61

고유성이 걱정되는 경우 항상 새 GUID를 구매하여 기존 GUID를 버릴 수 있습니다. 원한다면 eBay에 올려 놓겠습니다.


13
쿨-전체 세트에 대해 0에서 (2 ^ 128) -1까지 얼마입니까?
Steve314

23
1K GUID 당 $ 0.01 판매 중. 다음 60 분 안에 주문하면 대나무 바람 종소리를 넣습니다.
ctacke 5

7
내 세트는 더 독점적이고 더 높은 품질입니다. GUID 당 1 달러의 가치가있는 이중 확인 및 검증됩니다. 한 번에 전체 투자를 원하지 않으면 배치로 구입할 수도 있습니다. 그래도 배치 당 10 달러를 추가로 청구해야합니다.
Thomas

3
월간 요금제를 설정하고 적절한 가격으로 무제한 안내를 제공합니다. ^ 그 사람들은 당신을 사기하고 고가의 guids를 판매하려고합니다. 나는 당신에게 중국에서 만든 품질 guids를 판매합니다!
ErocM

47

개인적으로, "빅뱅"은 두 GUID가 충돌했을 때 발생했다고 생각합니다.


4
그렇게하기 위해서는 "특별한"종류의 프로그래머가 필요하다는 것을 기억하십시오.
AnthonyLambert

당신의 이론에 대한 당신의 추론을 듣고 싶습니다. 이를 바탕으로 새로운 종교를 시작하고 T.Cruise를 모집 할 수 있다고 생각합니다.
ErocM

@ErocM; "Brane cosmology"( en.wikipedia.org/wiki/Brane_cosmology ) 및 "Membrane (M-Theory)"( en.wikipedia.org/wiki/Membrane_(M-Theory) )을 참조하십시오. 아이디어는 두 개의 브레인이 새로운 우주에 닿으면 새로운 우주가 생성된다는 것입니다. 따라서 두 개의 GUID를 만지면 새 유니버스가 만들어지는 것으로 추론 할 수 있습니다.
AMissico

2
Timecop이 우리에게 무엇을 가르쳐 주면 같은 문제가 주어진 시간에 같은 공간을 차지할 수 없다는 것입니다. 따라서 두 GUID가 충돌 할 위치가 서로 충돌하면 결과로 발생하는 폭발로 인해 블랙홀이 생성되어 전체 우주가 움켜 쥐게됩니다. 실제로, 그것은 우주를 만들지 않고 그것을 파괴 할 것입니다.
AJC

42

양자 bogosort 알고리즘 의 변형으로 O (1) 시간에이를 표시 할 수 있습니다 .

Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
if(g1 != g2) Universe.Current.Destroy();

21
Destroy ()를 호출 할 때 예외가 발생합니다. 본문에 따르면 컴퓨터에는 현재 우주를 파괴하는 데 필요한 하드웨어가 부족하다고 생각합니다. 어디서 구할 수 있는지 아십니까?
Steven Sudit

11
@Steven : 아니, 일부 경영진은 API가 대중에게 얼마나 나쁜지 걱정하고 너무나 "보안상의 이유로"실패하도록 지시했습니다. 메소드의 소스를 보면 한 줄만 있습니다 : throw new MundaneHardwareException();. 어쨌든, CERN의 직원들에게는 속임수를 쓰는 일종의 Big Hadron Thingy가 있다고 들었습니다.
R. Martinho Fernandes

7
@Martinho : 아, 알겠습니다. 로 대체 Universe.Current.Destroy()해 보겠습니다 Cern.Lhc.DestroyThisUniverse().
Steven Sudit

61
하스켈에 프로그래밍 한 이유가 있다는 것을 알았습니다. 이러한 부작용은 무섭습니다.
Edward KMETT

6
"우주가 무엇을위한 것인지, 왜 그것이 여기에 있는지를 발견 한 사람이라면 즉시 사라지고 더 이상 설명 할 수없는 것으로 대체 될 것이라는 이론이있다. 이미 일어난 일이 또 다른 이론이다. " - 더글러스 애덤스, 은하수를 여행하는 히치하이커를위한 안내서
마이크 Pirnat

28

두 GUID는 고유 할 가능성이 높습니다 (같지 않음).

이 SO 항목Wikipedia를 참조하십시오.

생성 된 각 GUID가 고유 한 것은 아니지만 총 고유 키 수 (2 ^ 128 또는 3.4 × 10 ^ 38)는 너무 커서 같은 수의 두 번 생성 될 확률이 매우 작습니다. 예를 들어, 약 5 × 10 ^ 22 개의 별을 포함하는 관측 가능한 우주를 생각해보십시오. 모든 별은 6.8 × 10 ^ 15의 보편적으로 독특한 GUID를 가질 수 있습니다.

따라서 아마도 당신은 수십억 년을 기다려야 할 것이며, 우주가 끝나기 전에 우주에 도달하기를 바랍니다.


그렇다면 2 ^ 128은 가능한 개수의 guid가 아닌가?
Kai

21
그것은. 2 ^ 128이 작은 이유는 무엇이라고 생각하십니까?
jrockway

예, 2 ^ 128은 가능한 개수의 guid입니다.
Graviton

3
그것은 많은 지옥입니다. $ irb >> 2**128 => 340282366920938463463374607431768211456
adamJLev

45
@Infinity-당신도?
오스틴 리차드슨

27

[업데이트 :] 아래 의견에서 알 수 있듯이 최신 MS GUID는 V4이며 GUID 생성의 일부로 MAC 주소를 사용하지 않습니다.하지만 MS에서 V5 구현에 대한 징후는 보지 못했습니다. 알려주세요 링크). 그러나 V4에서는 시간이 여전히 중요한 요소이며 GUID의 중복에 대한 가능성은 실제 사용과 관련이 없을 정도로 작습니다. OP가 시도한 것과 같은 단일 시스템 테스트에서 중복 GUID를 생성하지는 않을 것입니다.

이러한 답변의 대부분에는 Microsoft의 GUID 구현에 대한 중요한 요점이 없습니다. GUID의 첫 번째 부분은 타임 스탬프를 기반으로하며 다른 부분은 네트워크 카드의 MAC 주소 (또는 NIC가 설치되지 않은 경우 임의의 숫자)를 기반으로합니다.

내가 이것을 올바르게 이해한다면, GUID를 복제하는 유일한 확실한 방법은 MAC 주소가 같고 두 시스템의 시계가 정확히 같은 시간에 있었던 여러 시스템에서 동시에 GUID 생성을 실행하는 것입니다. 발생했습니다 (타임 스탬프는 올바르게 이해하면 밀리 초를 기준으로 함) .... 그럼에도 불구하고 숫자에 임의의 다른 비트가 많으므로 확률은 여전히 ​​작습니다.

모든 실질적인 목적을 위해 GUID는 보편적으로 독특합니다.

"The Old New Thing"블로그에 MS GUID에 대한 꽤 좋은 설명이 있습니다.


3
가상화를 사용할 때 실제로 가능합니다. 당신은 할 수 있고 중복 된 guids를 얻습니다.
Goran

8
MAC 주소 부분에서는 Raymond가 오래되었지만 Microsoft는 더 이상 사용하지 않습니다. V1 및 V4 Guid의 차이점에 대해서는 en.wikipedia.org/wiki/GUID#Algorithm 을 참조하십시오 .
Michael Stum

1
이것은 더 이상 사실이 아닙니다. 현재 V5 방식은 128 비트의 순수한 의사 난수입니다.
Edward KMETT

내가 당신보다 한 달 뒤에 한 모든 일을 어떻게 말하고 16 점을 얻었고 여전히 0을 가지고 있습니까?
AnthonyLambert

1
야 토니, 그게 뭔가 이상해 내가 게시물에 대답했을 때, 단지 3-4 개의 답변이 있었고, 당신의 것을 본 기억이 없었습니다. 만약 내가 있었다면, 나는 단지 그것을 찬성했을 것입니다. 나는 일반적으로 이미 충분히 잘 설명하는 다른 답변이있을 때 질문에 대답하지 않습니다 (그래서 전반적인 대답이 다소 낮습니다).
Stephen M. Redd

23

다음은 코드의 여러 곳에서 guid 고유성을 확인하려는 경우 사용할 수있는 멋진 확장 방법입니다.

internal static class GuidExt
{
    public static bool IsUnique(this Guid guid)
    {
        while (guid != Guid.NewGuid())
        { }
        return false;
    }
}

호출하려면 새 guid를 생성 할 때마다 Guid.IsUnique를 호출하면됩니다.

Guid g = Guid.NewGuid();
if (!g.IsUnique())
{
    throw new GuidIsNotUniqueException();
}

... 아마, 나는 그것을 1 라운드에서 제대로 얻었는지 확인하기 위해 두 번 부르는 것이 좋습니다.


2
이것이이 this guid세상 어느 곳에서도 생성되지 않았 음을 어떻게 보장 합니까? : p 우리는 세계 안내 수영장이 필요합니다. :)
nawfal

19

2 ^ 128까지 계산-야심 찬.

하지 - 우리는 기계 당 초당 2 ^ 32 ID에 셀 수 있다고 가정하자 조차 4,300,000,000초 당이 아니다 이후, 야심을. 2 ^ 32 머신을 해당 태스크에 전용 할 수 있습니다. 또한 2 ^ 32 개의 문명을 확보하여 동일한 자원을 작업에 바칩니다.

지금까지 초당 2 ^ 96 개의 ID를 계산할 수 있습니다. 즉, 2 ^ 32 초 (136 년이 조금 넘음) 동안 계산됩니다.

이제 우리가 필요로하는 것은 4,294,967,296 대의 기계에 4,294,967,296 개의 문명을 얻는 것입니다. 각 기계는 초당 4,294,967,296 개의 ID를 계산할 수 있습니다. 순전히 136 년 동안이 과제를 수행 할 것입니다. -)


17

830 억 년의 실행 시간이 당신을 놀라게하지 않는다면, 생성 된 GUID를 어딘가에 저장하여 사본이 있는지 확인해야한다고 생각하십시오. 2 ^ 128 16 바이트 숫자를 저장하면 4951760157141521099596496896 테라 바이트의 RAM을 사전에 할당하기 만하면되므로 모든 것을 수용 할 수있는 컴퓨터가 있다고 가정하고 각각 10g 씩 테라 바이트 DIMM을 구입할 수있는 장소를 찾게됩니다. 지구 질량이 8 개를 초과하므로 "Run"을 누르기 전에 현재 궤도에서 심각하게 이동할 수 있습니다. 두 번 생각!


12
for(begin; begin<end; begin)
    Console.WriteLine(System.Guid.NewGuid().ToString());

증분하지 begin않으므로 조건 begin < end이 항상 참입니다.


1
아니오-내가 bigint를 반복 할 수없는 원인
Kai

3
그가 루핑 대 루핑보다 340282366920938463463374607431768211456 번 반복하는 것이 정말 중요합니까?
Jay

3
그래서 ... 당신은 오히려 340282366920938463463374607431768211456 번 또는 영원히 펀치 될 것입니다!?!?!?
ErocM

실제로 이것은 실제로 질문에 대한 답변입니다! 그리고 전혀 투표 : p
nawfal


9

아마도 Guids 생성 알고리즘이 실제로 임의의 숫자를 생성하는 것이 아니라 실제로 << 2 ^ 128 주기로 순환하고 있다고 믿을만한 이유가있을 것입니다.

예를 들어, 일부 비트 값을 고정하는 GUID를 도출하는 데 사용되는 RFC4122 방법.

사이클링의 증거는 가능한 기간의 크기에 달려 있습니다.

짧은 기간 동안 해시 테이블 (GUID)-> GUID가 충돌하는 경우 GUID가 일치하지 않으면 (해당되는 경우 종료) 해시 테이블이 접근 방식이 될 수 있습니다. 또한 시간의 임의 부분 만 교체하는 것을 고려하십시오.

궁극적으로 충돌 사이의 최대 기간이 충분히 크고 사전에 알려지지 않은 경우 모든 방법은 충돌이 존재하는 경우 충돌이 발견 될 확률 만 산출합니다.

Guid를 생성하는 방법이 클럭 기반 (RFC 참조) 인 경우 (a) 클럭이 줄 바꿈되기까지 충분히 오래 기다릴 수 없기 때문에 충돌이 존재하는지 확인할 수 없습니다. 또는 (b) 충돌을 강제하기 위해 클럭 틱 내에 충분한 Guid를 요청할 수 없습니다.

또는 Guid의 비트 간 통계 관계 또는 Guid 간의 비트 상관 관계를 표시 할 수 있습니다. 이러한 관계로 인해 실제 충돌을 찾을 수 없어도 알고리즘에 결함이있을 가능성이 높습니다.

물론 Guids가 충돌 할 수 있다는 것을 증명하고 싶다면 프로그램이 아니라 수학적 증거가 답입니다.


8

그래픽 카드 업그레이드에 대해 언급 한 사람이 아무도없는 이유를 모르겠습니다. 고급 NVIDIA Quadro FX 4800 또는 그 밖의 제품 (192 CUDA 코어)이 있다면 더 빨라질 것입니다 ...

물론 몇 개의 NVIDIA Qadro Plex 2200 S4 (각각 960 CUDA 코어)를 감당할 수 있다면이 계산은 실제로 비명을 지 릅니다 . 아마도 NVIDIA는 PR 스턴트로 "기술 데모"를 위해 몇 가지를 기꺼이 빌려줄 것입니까?

분명히 그들은이 역사적인 계산의 일부가되고 싶어합니다 ...


흠 ..... 직장의 10,000 노드 그리드에서 실행할 수 있습니다.
AnthonyLambert

8

그러나 복제본 이 있는지 확인해야 하거나 복제본이있을 있는 경우에만 신경 써야합니다 . 생일이 같은 사람이 두 명인지 확인하려면 윤년을 세지 않고 366 명이 필요합니다. 같은 생일을 가진 두 사람을 가질 확률이 50 % 이상이면 23 명만 있으면됩니다. 그게 생일 문제 야 입니다.

32 비트가있는 경우 중복 가능성이 50 %보다 큰 77,163 개의 값만 있으면됩니다. 사용해보십시오 :

Random baseRandom = new Random(0);

int DuplicateIntegerTest(int interations)
{
    Random r = new Random(baseRandom.Next());
    int[] ints = new int[interations];
    for (int i = 0; i < ints.Length; i++)
    {
        ints[i] = r.Next();
    }
    Array.Sort(ints);
    for (int i = 1; i < ints.Length; i++)
    {
        if (ints[i] == ints[i - 1])
            return 1;
    }
    return 0;
}

void DoTest()
{
    baseRandom = new Random(0);
    int count = 0;
    int duplicates = 0;
    for (int i = 0; i < 1000; i++)
    {
        count++;
        duplicates += DuplicateIntegerTest(77163);
    }
    Console.WriteLine("{0} iterations had {1} with duplicates", count, duplicates);
}

1000 iterations had 737 with duplicates

이제 128 비트가 많으므로 여전히 많은 항목을 말하면서 충돌 가능성이 낮습니다. 근사값을 사용하여 주어진 확률에 대해 다음 수의 레코드가 필요합니다.

  • 1/1000의 충돌 가능성으로 80 억
  • 충돌 가능성 50 % 확률로 217 억
  • 충돌 가능성 90 % 확률로 396 억

매년 약 1E14 개의 전자 메일이 전송되므로 동일한 GUID로 두 개를 가질 확률이 90 %가되기 전에이 수준에서 약 400,000 년이 될 것입니다. 복제본을 찾기 전에 우주의 시대 나 태양이 차가워 질 것입니다.


7

모두 중요한 요점이 없습니까?

GUID가 전역 적으로 독창적 일 가능성이 높은 두 가지를 사용하여 생성 된 것으로 생각했습니다. 하나는 사용자가있는 컴퓨터의 MAC 주소로 시드되고 두 개는 생성 된 시간에 임의의 숫자를 더한 것입니다.

따라서 실제 머신에서 실행하고 GUID에서 시간을 표시하기 위해 머신이 사용하는 최소 시간 내에 모든 추측을 실행하지 않으면 시스템 호출을 사용하여 추측 한 수에 관계없이 동일한 숫자를 생성하지 않습니다.

GUID가 실제로 만들어지는 방법을 알고 있다면 실제로 상당히 추측하는 시간이 단축 될 것입니다.

토니


3
모든 GUID가 이런 식으로 생성되는 것은 아닙니다. Kai는 GUID를 만드는 데 사용 된 타임 스탬프가 GUID를 만드는 데 사용한 시간 소인이 다시 사용될 때까지 충분한 시간을 감쌀 때까지 기다려야합니다.
Dour High Arch 2011

3
Guids는 2000 년 또는 2001 년 이후로 mac 주소를 기반으로하지 않았습니다. NT4 및 / 또는 Win2k 서비스 팩 중 하나에서 알고리즘을 완전히 변경했습니다. 그것들은 이제 임의의 guid의 종류를 식별하는 몇 비트를 뺀 난수 생성기에 의해 생성됩니다.
KristoferA

4
모든 GUID가 Windows 플랫폼에서 제공되는 것은 아닙니다.
AnthonyLambert 2011

OP는 C #을 언급하므로 Windows입니다. 게다가 V4 GUID는 Windows 전용입니까?
Steven Sudit

5
@Martinho : Ah,하지만 GuidTest.cs의 Guid에 대한 Mono의 단위 테스트에는 두 개의 새로운 GUID를 생성하고 동일한 지 여부에 따라 실패하는지 확인하는 방법이 포함되어 있습니다. Mono가 성공적으로 빌드되면 GUID가 고유하다는 것을 절대적으로 확신 할 수 있습니다! :-)
Steven Sudit

6

GUID를 해시 할 수 있습니다. 그렇게하면 결과가 훨씬 빨라집니다.

물론 여러 스레드를 동시에 실행하는 것도 좋은 생각입니다. 이렇게하면 경쟁 조건이 다른 스레드에서 동일한 GUID를 두 번 생성 할 가능성이 높아집니다.


6

4 비트는 버전 번호를 보유하므로 GUID는 124 비트입니다.


이것을 코멘트로 추가하지 않는 이유 : 아무도 언급하지 않았으며, 누가 이것을 말해야하는지 모르겠습니다. :)
Behrooz

내가 작성한 일부 "실제"앱에서 ~ 260k 행의 테이블에서 Guid 충돌이 발생했습니다. (MSSQL 2008 R2 Express).
Behrooz

6
  1. 뉴욕시의 극저온 연구소로 이동하십시오.
  2. (대략) 1990 년 동안 자신을 얼리십시오.
  3. Planet Express에서 취업하십시오.
  4. 새로운 CPU를 구입하십시오. 컴퓨터를 만들고 프로그램을 실행 한 다음 종말 기계와 같은 의사 영구 운동 기계를 사용하여 안전한 장소에 배치하십시오.
  5. 타임머신이 발명 될 때까지 기다리십시오.
  6. 타임머신을 사용하여 미래로 이동하십시오. 1YHz 128 비트 CPU를 구입 3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 ps한 경우 프로그램 실행을 시작한 후로 이동 하십시오.
  7. ...?
  8. 이익!!!

... 1GHz CPU보다 빠른 10,783,1271YHz CPU 1,000,000,000,000,000(또는 1,125,899,906,842,624이진 접두사 사용을 선호하는 경우)보다 몇 년 이 걸립니다 .

따라서 계산이 완료되기를 기다리는 대신 다른 n비둘기가 집을 가져 갔기 때문에 집을 잃은 비둘기에게 먹이를주는 것이 좋습니다 . :(

또는 128 비트 양자 컴퓨터가 발명 될 때까지 기다릴 수 있습니다. 그런 다음 합리적인 시간에 프로그램을 사용하여 GUID가 고유하지 않다는 것을 증명할 수 있습니다.


나는이 답변에서 슈퍼 영웅 참조를 기다리고있었습니다-포스터로 실패 : p-굉장한 적은.
IbrarMumtaz

4

begin = begin + new BigInteger((long)1)begin ++ 대신 사용해 보셨습니까 ?


2
이 질문에 대한 답변이 아무도 없습니다 : P
nawfal

4

생성되는 UUID의 수가 무어의 법칙을 따르는 경우, 예측 가능한 미래에 GUID가 절대로 부족하지 않다는 인상은 거짓입니다.

2 ^ 128 UUID를 사용하면 모든 UUID가 다 떨어지기까지 18 개월 만 걸립니다. * Log2 (2 ^ 128) ~ = 192 년.

그리고 UUID를 대량 채택한 이후 지난 몇 년 동안 (통계적인 증거없이) UUID를 생성하는 속도가 무어의 법칙보다 훨씬 빠르게 증가하고 있다고 생각합니다. 다시 말해, UUID 위기를 다룰 때까지 우리는 아마도 192 년이 채되지 않았을 것입니다. 그것은 우주의 종말보다 훨씬 빠릅니다.

그러나 우리는 2012 년 말까지 그것들을 다 떨어 뜨리지 않을 것이기 때문에 문제에 대해 걱정하기 위해 다른 종에게 맡길 것입니다.


3

GUID 생성 코드의 버그 확률은 충돌을 생성하는 알고리즘의 확률보다 훨씬 높습니다. GUID를 테스트하기위한 코드 버그 가능성이 더 큽니다. 포기 해


2

오류는 있지만 프로그램은 GUID가 고유하지 않다는 증거를 보여줍니다. 반대를 증명하려는 사람들은 요점을 놓치고 있습니다. 이 문장은 일부 GUID 변형의 약한 구현을 증명합니다.

GUID는 정의에 따라 고유하지 않아도되며 정의에 따라 매우 고유합니다. 당신은 방금 높은 의미를 다듬 었습니다. 버전, 구현 자 (MS 또는 기타), VM 사용 등에 따라 크게 변경되는 정의에 따라 다릅니다. (이전 게시물의 링크 참조)

포인트를 증명하기 위해 128 비트 테이블을 단축 할 수 있습니다. 가장 좋은 해결책은 해시 수식을 사용하여 테이블을 중복으로 줄인 다음 해시가 충돌하고 GUID를 다시 생성하면 전체 값을 사용하는 것입니다. 다른 위치에서 실행하는 경우 해시 / 전체 키 쌍을 중앙 위치에 저장합니다.

추신 : 목표가 x 개의 다른 값을 생성하는 것이라면이 너비의 해시 테이블을 만들고 해시 값을 확인하십시오.


2

여기 모닥불에 p ** s는 아니지만 실제로 발생합니다. 그렇습니다. 네가이 농담을 한 농담을 이해하지만 GUID는 원칙적으로 독특합니다. 버그가 있기 때문에이 스레드에 부딪 쳤습니다. WP7 에뮬레이터에서 부팅 할 때마다 처음 호출 될 때 동일한 GUID를 제공합니다. 따라서 이론적으로 충돌이 발생할 수없는 곳에서 GUI를 생성하는 데 문제가 있으면 중복을 얻을 수 있습니다

http://forums.create.msdn.com/forums/p/92086/597310.aspx#597310


1

Guid 생성의 일부는 현재 컴퓨터의 시간을 기반으로하기 때문에 중복 Guid를 얻는 이론은 다음과 같습니다.

  1. Windows를 새로 설치하십시오.
  2. Windows가 부팅 될 때처럼 시간을 2010-01-01 12:00:00으로 재설정하는 시작 스크립트를 만듭니다.
  3. 시작 스크립트 직후에 응용 프로그램이 Guid를 생성하도록 트리거합니다.
  4. 후속 Windows 부팅에서 발생할 수있는 미묘한 차이점을 배제하도록이 Windows 설치를 복제하십시오.
  5. 이 이미지로 하드 드라이브를 다시 이미징하고 머신을 몇 번 부팅하십시오.

0

나를 위해 .. 단일 코어가 UUIDv1을 생성하는 데 걸리는 시간은 고유 할 것입니다. 멀티 코어 상황에서도 UUID 생성기가 특정 리소스에 대해 한 번에 하나의 UUID 만 생성하도록 허용하는 경우 (리소스가 주소의 일부이기 때문에 여러 리소스가 동일한 UUID를 완전히 사용할 수 있음을 명심하십시오) 타임 스탬프가 소실 될 때까지 지속될 수있는 충분한 UUID가 있습니다. 그 시점에서 나는 당신이 관심을 가질 것이라고 정말로 의심합니다.


0

해결책도 있습니다 :

int main()
{
  QUuid uuid;
  while ( (uuid = QUuid::createUuid()) != QUuid::createUuid() ) { }
  std::cout << "Aha! I've found one! " << qPrintable( uuid.toString() ) << std::endl;
}

참고 : Qt가 필요하지만 오래 실행하면 찾을 수 있음을 보증합니다.

(참고 참고 : 실제로, 지금 살펴보면, 생성 알고리즘에 대해 나중에 생성되는 두 개의 UUID가 충돌하는 것을 막을 수 있지만 뭔가 의심 스럽습니다.)


0

GUID가 고유하지 않다는 것을 증명하는 유일한 솔루션은 World GUID Pool을 사용하는 것입니다. GUID가 생성 될 때마다 조직에 등록되어야합니다. 또는 모든 GUID 생성기에서 자동으로 등록해야하고 인터넷에 연결되어 있어야한다는 표준화가 포함되어있을 수 있습니다.

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