GUID'in benzersiz olmadığının basit kanıtı [kapalı]


323

Basit bir test programında bir GUID'in benzersiz olmadığını kanıtlamak istiyorum. Aşağıdaki kodun saatlerce çalışmasını bekledim, ancak çalışmıyor. Nasıl çalıştırabilirim?

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 # kullanıyorum.


107
Bir yazılım geliştiricisi olarak, bir kullanıcı size gelip "işe yaramıyor" derse ne söylerdiniz?
JoshJordan

152
Birkaç trilyon yıl bekleyin.
hobbs

67
Upmodded çünkü bu bugün çevrimiçi olarak gördüğüm en eğlenceli şey.
jrockway

32
@jrockway - lol. Bu soru hakkında temelde yanlış olmayan bir şey bulmakta zorlanıyorum. Ne kadar uzun süre bakarsam o kadar komik olur.
tylerl

243
Sadece küresel olarak eşsizdir, bu yüzden sadece gezegenimizde benzersizdir. Gerçekten benzersiz bir kimlik istiyorsanız, evrensel olarak benzersiz bir kimlik (UUID) kullanmanız gerekir . Sadece evrenimizdeki benzersizlikle ilgilendiğinizi varsayıyorum. :-)
tvanfosson

Yanıtlar:


407

Kai, iş parçacıklarını kullanarak istediğinizi yapacak bir program sağladım. Aşağıdaki şartlar altında lisanslanmıştır: Çalıştırdığınız CPU çekirdeği başına saatte 0.0001 $ ödemeniz gerekir. Ücretler her takvim ayının sonunda ödenir. Paypal hesap detayları için en kısa zamanda lütfen benimle iletişime geçin.

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?");
        }
    }
}

Not: Paralel uzantılar kitaplığını denemek istedim. Kolaydı.

OutOfMemoryException'ı kontrol akışı olarak kullanmak yanlış geliyor.

DÜZENLE

Görünüşe göre bu hala oy alıyor. Bu yüzden GC.KeepAlive () sorununu çözdüm. Ve C # 4 ile çalışacak şekilde değiştirdi.

Ve destek şartlarını açıklığa kavuşturmak için: destek yalnızca 28 / Şubat / 2010'da kullanılabilir. Lütfen yalnızca o gün destek talepleri yapmak için bir zaman makinesi kullanın.

DÜZENLEME 2 Her zaman olduğu gibi, GC hafızayı yönetmede benden daha iyi bir iş çıkarır; daha önce kendim yapma girişimleri başarısızlığa mahkum edildi.


120
Bu son Konsol.WriteLine beni çok güldürdü. Bence bunun CommonlyAcceptedCosmologicTheoriesWrongExceptionyerine atmalısın .
R. Martinho Fernandes

17
bunu Kabul Edildi olarak işaretlemek, @Kai'nin @ligos tarafından şart koşulan şartları kabul ettiği anlamına mı gelir?
kb.

3
Ayar reserveSomeRam = null;aslında hiçbir şey başaramaz.
DevinB

4
@devinb lütfen açıkla? GC'nin yapabilmesi Collect()için önceden tahsis edilen baytları serbest bıraktığı görülüyor . Neden hiçbir şey başaramıyor?
mythz

3
GuidCollisionDetector. İsmin potansiyeli var
Ufuk Hacıoğulları

226

Bu saatten fazla sürecek. 1 GHz'de döngüye girdiğini varsayarsak (ki olmayacak - bundan çok daha yavaş olacaktır), 10790283070806014188970 yıl boyunca çalışacaktır. Bu, evrenin yaşından yaklaşık 83 milyar kat daha uzun.

Moores yasasının geçerli olduğunu varsayarsak , bu programı çalıştırmamak, birkaç yüz yıl beklemek ve milyarlarca kez daha hızlı bir bilgisayarda çalıştırmak çok daha hızlı olacaktır. Aslında, CPU hızlarının iki katına çıkmasından (yaklaşık 18 ay) daha uzun süren herhangi bir program, CPU hızları yükselene kadar beklerseniz ve çalıştırmadan önce yeni bir CPU satın alırsanız (daha önce yazmazsanız) askıya alınabilir ve yeni donanımda devam ettirilebilir).


27
lanet olsun - belki de kılavuz oluşturan servikal iplikler daha iyi bir fikirdir?
Kai

107
Dört çekirdekli işlemcideki 4 iş parçacığı, evrenin yaşının 20 milyar katında çalışmasını sağlayacaktır - bu yüzden evet, bu çok yardımcı olacaktır.
09:10

34
Bunun bir trol olduğundan şüpheliyim, ancak kapalı olma şansı yok: konuları büyülü değil. Bir iş parçacığında saniyede bir milyar işlem yapabiliyorsanız, on iş parçacığına gitmek her birinin sık sık 1/10 çalıştığı anlamına gelir. Her iplik saniyede 100 M işlem yapar; saniyede toplam işlem sayısı artırılmaz. Saniyede işlem sayısını artırmanın yolu daha fazla bilgisayar satın almaktır. Bir milyar daha fazla bilgisayar satın aldığınızı varsayalım. Bu, sorunu sadece dört saatten fazla olan 10790283070806 yıla indirecek.
Eric Lippert

10
Bence rjmunro her iş parçacığının ayrı bir çekirdek üzerinde çalışacağını varsayıyor; 83 milyar evren / 4 çekirdek aslında yaklaşık 20 milyar evrene eşittir. Intel hisse senedi satın alma zamanı!
Dour Yüksek Kemeri

4
@Erik 83 milyar işlemci, evrenin şimdiye kadar var olduğu süre içinde yapabileceğiniz anlamına gelir. Yani bu bile neredeyse yeterli değil.
rjmunro

170

Bir GUID teorik olarak benzersiz değildir. İşte kanıtınız:

  • GUID 128 bitlik bir sayıdır
  • Eski GUID'leri yeniden kullanmadan 2 ^ 128 + 1 veya daha fazla GUID oluşturamazsınız

Ancak, güneşin tüm güç çıkışı bu görevi yerine getirmeye yönelmişse, bitmeden çok önce soğuyacaktır.

GUID'ler, bazıları belirli bir makinenin aynı GUID'yi iki kez oluşturmayacağını garanti etmek için özel önlemler alan bir dizi farklı taktik kullanılarak üretilebilir. Belirli bir algoritmada çakışma bulmak, GUID oluşturma yönteminizin kötü olduğunu, ancak genel olarak GUID'ler hakkında hiçbir şey kanıtlamayacağını gösterir.


44
Kurtarmak için Güvercin Deliği Prensibi!
yfeldblum

22
Güneş soğuk için +1 yorum. Şifreleme anahtarlarının anlamsızlığı> 256 bit hakkında ilginç bir yorum vardı. Olası tüm anahtar değerleri yinelemek, tüm evrenin sahip olduğundan daha fazla enerji gerektirir. CPU'da biraz geçiş yapmak, 2 ^ 256 kez çarpıldığında, evrendeki enerjiyi aşan gerçekten büyük bir sayı olan, E = mc2 kullanarak evrenin kütlesine ihtiyaç duyacağı küçük miktarda enerji (ısıyı üreten şeydir) gerektirir 2 ^ 227kg, güneşimiz 2 ^ 101kg yani 2 ^ 126 güneş!
Skizz

31
@Skizz: Bu sadece kaba kuvvet saldırıları için geçerlidir. Bir şifreleme şeması "kırıldığında", kaba kuvvetten daha kısa sürede çözülebileceği anlamına gelir, ancak çözme süresi anahtar boyutuyla orantılı kalır.
Steven Sudit

1
@StevenSudit: anahtar boyutunun üsüyle orantılı (P == NP hariç)
Ihar Bury

1
@Orlangur Bit cinsinden ölçülen anahtar boyutuyla orantılı.
Steven Sudit

137

Tabii ki GUID'ler çarpışabilir. GUID'ler 128 bit olduğundan, 2^128 + 1bunları oluşturun ve güvercin deliği prensibi ile bir çarpışma olması gerekir.

Ancak bir GUID'nin benzersiz olduğunu söylediğimizde, gerçekten kastettiğimiz, anahtar alanın o kadar büyük olduğu ve yanlışlıkla aynı GUID'yi iki kez oluşturmanın neredeyse imkansız olduğu (rastgele GUID'ler oluşturduğumuzu varsayarak).

nRastgele bir GUID dizisi oluşturursanız , en az bir çarpışma olasılığı yaklaşıktır p(n) = 1 - exp(-n^2 / 2 * 2^128)(bu, olası doğum günlerinin sayısıyla ilgili doğum günü problemidir2^128 ).

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

Bu sayıları somutlaştırmak 2^60 = 1.15e+18. Yani, saniyede bir milyar GUID oluşturursanız, 2^60rastgele GUID'ler oluşturmak 36 yılınızı alır ve o zaman bile bir çarpışma olasılığınız hala devam eder 1.95e-03. Önümüzdeki 36 yıl içinde bir çarpışma bulmanızdan ( ) hayatınızın bir noktasında öldürülme olasılığınız daha yüksektir 4.76e-03. İyi şanslar.


239
Hayatının bir noktasında öldürülürsen, olasılıklar sonunda olacak.
Michael Myers

25
@mmyers: Mükemmel bir nokta. Bu, şu anda öldürülme şansımın saçma derecede düşük olduğu anlamına geliyor, çünkü bu hayatımın sonu değil. Oh, bekleyin ...
Steven Sudit

Ayrıca, kısa bir süre içinde iki GUID yaratılırsa, aynı sistemde kullanılma şansları azdır. Bu nedenle, bu benzersizliği artırır.
AMissico

Bu sayılar ve doğum günü problemine referans anlamsızdır. GUID oluşturma algoritmaları, eşit olasılıkla tüm aralıkta değer üretmez. Aslında IIRC orijinal algoritma, üreten PC'nin MAC adresini + sonucun bir parçası olarak geçerli saati kullandı - bu, diğer bilgisayarlarda üretilen Kılavuzlarla çarpışma riskini azaltır, ancak elbette anahtar alanı azaltır.
Joe

17
Öldürülme olasılığının tüm insanlar için sabit olduğunu varsayıyorsunuz. Ancak forum yazılarında gizli açıklamalar yazan insanlar, ortalama bir insandan daha fazla öldürülme olasılığı olan insanlardır.
Jay

61

Benzersizlik konusunda endişeleriniz varsa her zaman yeni GUID'ler satın alabilirsiniz, böylece eskilerinizi atabilirsiniz. İsterseniz eBay'e biraz koyacağım.


13
Harika - 0'dan (2 ^ 128) -1'e kadar tüm set için ne kadar?
Steve314

23
Satışta, 1k GUID başına 0,01 USD. Önümüzdeki 60 dakika içinde sipariş verirseniz bazı bambu rüzgar çanlarını atacağım.
ctacke

7
Benim setim daha özel ve daha kaliteli. Çift kontrol edilir ve doğrulanır, bu da onları GUID başına 1 $ değerinde yapar. Tek seferde tam yatırım yapmak istemiyorsanız, bunları toplu olarak satın alabilirsiniz. Ben parti başına ekstra 10 $ şarj etmek zorunda kalacak.
Thomas

3
Size aylık bir plan hazırlayacağım ve size doğru fiyata sınırsız rehberler vereceğim. ^ Bu adamlar sizi dolandırmaya ve overpriced rehberleri satmaya çalışıyorlar. Size Çin'de yapılan kaliteli kılavuzları satacağım!
ErocM

47

Şahsen, "Büyük Patlama" nın iki GUID çarpıştığında ortaya çıktığını düşünüyorum.


4
Sadece unutmayın Bunu yapmak için "özel" bir programcı gerekir ...
AnthonyLambert

Teorinize olan aklınızı duymak istiyorum. Bence buna dayalı yeni bir din başlatabiliriz ve T.Cruise'i işe alabiliriz!
ErocM

@ErocM; Bkz. "Brane kozmolojisi" ( en.wikipedia.org/wiki/Brane_cosmology ) ve "Membran (M-Teorisi)" ( en.wikipedia.org/wiki/Membrane_(M-Theory) ). Fikir, iki dalın yeni bir evrene dokunmasıyla yaratılır. Bu nedenle, iki GUID dokunursa, böylece yeni bir evrenin yaratıldığını çıkarabilirsiniz.
AMissico

2
Timecop bize bir şey öğrettiyse, aynı maddenin herhangi bir zamanda aynı alanı işgal edemeyeceğidir. İki GUID nerede çarpışırsa, birbirlerini tüketecekler ve ortaya çıkan patlama tüm evreni yutacak bir kara delik oluşturacaktı. Yani gerçekte, bir Evren yaratmaz, onu yok eder.
AJC

42

Bunu kuantum bogosort algoritmasının bir varyantı ile O (1) zamanında gösterebilirsiniz .

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

21
Destroy () öğesini çağırırken bir istisna alıyorum. Metne göre, bilgisayarımın mevcut evreni yok etmek için gerekli donanıma sahip olmadığını düşünüyorum. Nereden edinebileceğimi biliyor musun?
Steven Sudit

11
@Steven: Hayır, bazı yönetim adamları API'nın halka ne kadar kötü görüneceği konusunda çok endişelendiler ve bunu "güvenlik nedenleriyle" her zaman başarısız olmaya zorladılar. Eğer yöntemin kaynağında bakarsak sadece bir satır var: throw new MundaneHardwareException();. Her neyse, CERN'deki çocukların hile yapabilecek bir çeşit Büyük Hadron Şeyleri olduğunu duydum ...
R. Martinho Fernandes

7
@Martinho: Ah, tamam. Ben değiştirilmesi içine bakacağız Universe.Current.Destroy()ile Cern.Lhc.DestroyThisUniverse().
Steven Sudit

61
Haskell'de programlamamın bir nedeni olduğunu biliyordum. Bu yan etkiler korkutucu hale geliyor.
Edward KMETT

6
"Bir kimse Evrenin tam olarak ne için olduğunu ve neden burada olduğunu keşfederse, anında ortadan kaybolacağını ve yerini daha tuhaf bir şekilde açıklanamayan bir şeyle değiştireceğini belirten bir teori var. ." - Douglas Adams, Otostopçunun Galaksi Rehberi
Mike Pirnat

28

Herhangi iki GUID büyük olasılıkla benzersizdir (eşit değildir).

Bkz bu SO girişi ve gelen Vikipedi

Oluşturulan her GUID'in benzersiz olduğu garanti edilmese de, toplam benzersiz anahtar sayısı (2 ^ 128 veya 3.4 × 10 ^ 38) o kadar büyüktür ki aynı sayının iki kez üretilme olasılığı çok azdır. Örneğin, yaklaşık 5 × 10 ^ 22 yıldız içeren gözlemlenebilir evreni düşünün; her yıldız, evrensel olarak benzersiz GUID'lere 6.8 × 10 ^ 15 sahip olabilir.

Bu yüzden muhtemelen milyarlarca yıl daha beklemelisiniz ve bunun sona erdiğini bildiğimiz için evrenden birine çarpmanızı umuyoruz.


2 ^ 128 doğru sayıda olası kılavuz değil mi?
Kai

21
Bu. Neden 2 ^ 128'in küçük bir sayı olduğunu düşünüyorsunuz?
jrockway

Evet, 2 ^ 128 doğru sayıda olası kılavuzdur.
Graviton

3
Bu bir numara. $ irb >> 2**128 => 340282366920938463463374607431768211456
adamJLev

45
@Infinity - Senin için bile mi?
Austin Richardson

27

[Güncelleme:] Aşağıdaki yorumların işaret ettiği gibi, daha yeni MS GUID'leri V4'tür ve MAC adresini GUID neslinin bir parçası olarak kullanmazlar (MS'den bir V5 uygulaması belirtisi görmedim, bu yüzden eğer bana bildiren bağlantı). Bununla birlikte V4 ile, zaman hala bir faktördür ve GUID'lerin çoğaltılmasına karşı olasılıklar, herhangi bir pratik kullanım için önemsiz olmaya devam etmektedir. Kesinlikle OP yapmaya çalıştığı gibi tek bir sistem testinden yinelenen bir GUID üretme olasılığınız yoktur.

Bu yanıtların çoğunda Microsoft'un GUID uygulaması hakkında önemli bir nokta eksik. GUID'in ilk kısmı bir zaman damgasına, diğer kısmı ise ağ kartının MAC adresine (veya NIC takılı değilse rastgele bir sayıya) dayanır.

Bunu doğru anlarsam, bir GUID'yi çoğaltmanın tek güvenilir yolunun, MAC adreslerinin aynı olduğu VE her iki sistemdeki saatlerin aynı zamanda aynı zamanda olduğu birden çok makinede eşzamanlı GUID nesilleri çalıştırmak olduğu anlamına gelir. (doğru anladıysam zaman damgası milisaniyeye dayanır) .... o zaman bile rastgele sayıdaki bir sürü başka bit vardır, bu yüzden oranlar hala kaybolmaktadır.

Tüm pratik amaçlar için GUID'ler evrensel olarak benzersizdir.

"Eski Yeni Şey" blogunda MS GUID hakkında oldukça iyi bir açıklama var


3
Bu aslında sanallaştırma kullanırken yapılabilir. Yinelenen kılavuzlar alabilirsiniz ve alabilirsiniz.
Goran

8
Raymond MAC Adresi bölümünde modası geçmiş, Microsoft artık bunları kullanmıyor. Bkz en.wikipedia.org/wiki/GUID#Algorithm V1 ve V4 GUID'lerini arasındaki farkın.
Michael Stum

1
Artık durum böyle değil. Mevcut V5 şeması sadece 128 bit saf sözde iyiliktir.
Edward KMETT

Bir ay sonra yaptığım her şeyi nasıl söylersin ve 16 puan alıyorsun ve hala 0 var mı?
AnthonyLambert

1
Ya Tony, bununla tuhaf bir şeyler var. Gönderiyi yanıtladığımda, sadece 3 veya 4 cevap vardı ve sizinkini gördüğümü hatırlamıyordum ... Eğer olsaydım, sadece iptal etmiş olurdum. Genellikle yeterince iyi kapsayan başka cevaplar olduğunda soruları cevaplamıyorum (bu yüzden muhtemelen oldukça düşük bir genel temsilciye sahibim).
Stephen M. Redd

23

Kodunuzdaki birçok yerde guid benzersizliğini kontrol etmek istiyorsanız kullanabileceğiniz şık küçük bir uzantı yöntemi.

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

Bunu aramak için, yeni bir rehber oluşturduğunuzda Guid.IsUnique'yi aramanız yeterlidir ...

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

... heck, ilk turda doğru olduğundan emin olmak için iki kez aramanızı öneririm.


2
Bu, this guiddünyanın hiçbir yerinde asla üretilmemesini nasıl sağlar ? : p Heck bir dünya rehber havuzuna ihtiyacımız var. :)
nawfal

19

2 ^ 128 olarak sayılıyor - iddialı.

Makine başına saniyede 2 ^ 32 kimlik sayabileceğimizi düşünelim - bu iddialı değil , saniyede 4,3 milyar bile değil. Bu işe 2 ^ 32 makine ayıralım. Ayrıca, her biri için aynı kaynakları görev için 2 ^ 32 medeniyet alalım.

Şimdiye kadar, saniyede 2 ^ 96 kimlik sayabiliriz, yani 2 ^ 32 saniye (136 yıldan biraz fazla) sayacağız.

Şimdi, ihtiyacımız olan tek şey, her biri 4.294.967.296 makineye 4.294.967.296 medeniyet almak, her makine saniyede 4.294.967.296 kimliği sayabilir, sadece bu görev için önümüzdeki 136 yıl boyunca başlamamızı öneriyorum; -)


17

Peki, 83 milyar yıllık çalışma süresi sizi korkutmuyorsa, yinelenen olup olmadığınızı kontrol etmek için oluşturulan GUID'leri bir yerde saklamanız gerektiğini düşünün; 2 ^ 128 16 baytlık sayıları depolamak için sadece 4951760157141521099596496896 terabayt RAM ayırmanız gerekir, bu yüzden her şeye sığabilecek bir bilgisayara sahip olduğunuzu ve her nasılsa 10 gramda terabayt DIMM satın almak için bir yer bulduğunuzu hayal edin. 8'den fazla Dünya kütlesini tartın, böylece "Run" tuşuna basmadan önce mevcut yörüngeden ciddi şekilde kaydırabilirsiniz. İki kere düşün!


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

Artış yapmıyorsunuz, beginbu yüzden durum begin < endher zaman doğrudur.


1
hayır - çünkü ben yinelenemiyorum bigint
Kai

3
340282366920938463463374607431768211456 kez döngüye karşı sonsuza dek döngüye girmesi gerçekten önemli mi?
Jay

3
yani ... 340282366920938463463374607431768211456 kez mi yoksa sonsuza dek mi yumruklansın??!?!?
ErocM

aslında soruya gerçekten cevap veren budur! ve hiç oy yok: p
nawfal


9

Muhtemelen Kılavuzları üretmek için algoritmanın gerçekten rasgele sayılar üretmediğine, aslında << 2 ^ 128 periyodu ile döngüye girdiğine inanmak için nedeniniz var.

örneğin, bazı bitlerin değerlerini sabitleyen GUID'leri türetmek için kullanılan RFC4122 yöntemi.

Döngü kanıtı dönemin olası boyutuna bağlı olacaktır.

Küçük periyotlar için, GUID'ler eşleşmiyorsa (eşleşiyorsa sonlandırın) karma (GUID) -> GUID çarpışmada değiştirmeyle birlikte bir yaklaşım olabilir. Değişim yerine sadece zamanın rastgele bir kısmını yapmayı düşünün.

Nihayetinde, çarpışmalar arasındaki maksimum süre yeterince büyükse (ve önceden bilinmemektedir), herhangi bir yöntem sadece çarpışmanın mevcut olması halinde bulunma olasılığı verecektir.

Kılavuz oluşturma yöntemi saat temelli ise (bkz. RFC), çarpışma olup olmadığını belirlemek mümkün olmayabilir, çünkü (a) saatin yuvarlanması için yeterince uzun süre bekleyemeyeceksiniz, veya (b) bir saati işaretlemede bir çarpışmayı zorlamak için yeterli Rehber isteyemezsiniz.

Alternatif olarak, Rehber'deki bitler arasında istatistiksel bir ilişki veya Rehberler arasındaki bitlerin bir korelasyonunu gösterebilirsiniz. Böyle bir ilişki, gerçek bir çarpışma bulamadan algoritmanın kusurlu olmasını büyük olasılıkla sağlayabilir.

Tabii ki, sadece Rehberlerin çarpışabileceğini kanıtlamak istiyorsanız, cevap bir program değil, matematiksel bir kanıttır.


8

Neden hiç kimsenin grafik kartınızı yükseltmekten bahsetmediğini anlamıyorum ... Kesinlikle bir high-end NVIDIA Quadro FX 4800 veya bir şey (192 CUDA çekirdeği) varsa, bu daha hızlı gidecektir ...

Tabii ki birkaç NVIDIA Qadro Plex 2200 S4 (her biri 960 CUDA çekirdeğinde) alabilseydiniz, bu hesaplama gerçekten çığlık atardı . Belki de NVIDIA bir PR dublör olarak size bir "Teknoloji Gösteri" için birkaç kredi vermek istersiniz?

Elbette bu tarihi hesaplamanın bir parçası olmak istiyorlardı ...


hmmmm ..... İş yerinde 10.000 düğüm ızgaramızda çalıştırabilirim.
AnthonyLambert

8

Ama gerekiyor emin olun Eğer yinelenen bir örneği, ya da orada eğer sadece bakım yapmak olabilir kopyası olabilir. Aynı doğum gününe sahip iki kişiniz olduğundan emin olmak için 366 kişiye ihtiyacınız var (artık yıl saymıyor). Aynı doğum günü olan iki kişinin% 50'den fazla şansı olması için sadece 23 kişiye ihtiyacınız var. Bu doğum günü problemi .

32 bitiniz varsa,% 50'den fazla yinelenme şansına sahip olmak için sadece 77.163 değere ihtiyacınız vardır. Denemek:

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

Şimdi 128 bit çok fazla, bu yüzden hala düşük çarpışma şansı veren çok sayıda öğe konuşuyorsunuz. Bir tahmin kullanarak verilen oranlar için aşağıdaki kayıt sayısına ihtiyacınız olacaktır:

  • 1/1000 çarpışma şansı için 0.8 milyar milyar
  • % 50 çarpışma olasılığı için 21.7 milyar milyar
  • % 90 çarpışma olasılığı için 39.6 milyar milyar

Yılda yaklaşık 1E14 e-posta gönderilir, bu nedenle aynı GUID'ye sahip olma şansınız% 90 olmadan önce bu seviyede yaklaşık 400.000 yıl olurdu, ancak bu, 83 milyar bilgisayar çalıştırmanız gerektiğini söylemekten çok farklı yinelemeden önce evrenin yaşı ya da güneşin soğuması.


7

Hepiniz önemli bir noktayı kaçırmıyor musunuz?

GUID'lerin Küresel olarak benzersiz olma şansını oldukça yüksek yapan iki şey kullanılarak oluşturulduğunu düşündüm. Birincisi, üzerinde bulunduğunuz makinenin MAC adresi ile tohumlanır ve iki tanesi üretildikleri zamanı ve rastgele bir sayıyı kullanırlar.

Bu yüzden, gerçek makinede çalıştırmazsanız ve makinenin GUID'de bir zamanı temsil etmek için kullandığı en küçük sürede çalıştırırsanız, sistem çağrısını kullanarak kaç tahminde bulunursanız olun asla aynı numarayı üretemezsiniz.

Bir GUID gerçekte nasıl yapıldığını biliyorsanız aslında tahmin etme süresini oldukça kısaltır sanırım.

Tony


3
Tüm GUID'ler bu şekilde oluşturulmaz. Öyle olsalar bile Kai, GUID'yi oluşturmak için kullanılan zaman damgasının GUID oluşturmak için kullandığı zamanın tekrar kullanılmasına kadar beklemelidir.
Dour High Arch

3
Kılavuzlar 2000 veya 2001'den beri mac adresine dayanmamaktadır. NT4 ve / veya Win2k için hizmet paketlerinden biri olarak algoritmayı tamamen değiştirdiler. Şimdi rastgele bir sayı üreteci tarafından üretilir, eksi ne tür bir rehber olduğunu tanımlayan birkaç bit.
KristoferA

4
tüm GUID'ler Windows platformlarından gelmiyor ...
AnthonyLambert

OP, C # 'dan bahsediyor, bu yüzden Windows. Ayrıca, V4 GUID sadece Windows için mi?
Steven Sudit

5
@Martinho: Ah, ama Mono'nun GuidTest.cs'deki Guid için birim testi, iki yeni GUID oluşturan ve eşit olup olmadığını kontrol eden bir yöntem içeriyor. Mono başarılı bir şekilde kuruldukça, GUID'lerinin benzersiz olduğundan kesinlikle emin olabiliriz! :-)
Steven Sudit

6

GUID'leri karma yapabilirsiniz. Bu şekilde, sonucu çok daha hızlı almalısınız.

Oh, elbette, aynı anda birden fazla iş parçacığı çalıştırmak da iyi bir fikirdir, bu şekilde farklı iş parçacıkları üzerinde aynı GUID'yi iki kez üreten bir yarış koşulunun şansını artıracaksınız.


6

GUID'ler 124 bittir çünkü 4 bit sürüm numarasını tutar.


Bunu bir yorum olarak eklememenin sebebi: hiç kimse bundan bahsetmedi ve bunu kimin bana söylemesi gerektiğini bilmiyorum. :)
Behrooz

Hooooraaaay ben yaptım. Yazdığım bazı "gerçek" app, ~ 260k Satırları ile bir tabloda bir Guid çarpışma var. (MSSQL 2008 R2 Express).
Behrooz

6
  1. New York'taki kriyojenik laboratuvarına git.
  2. Kendinizi (kabaca) 1990 yıl boyunca dondurun.
  3. Planet Express'te bir iş bul.
  4. Yepyeni bir CPU satın alın. Bir bilgisayar oluşturun, programı çalıştırın ve kıyamet günü makinesi gibi sahte bir sürekli hareket makinesiyle güvenli bir yere yerleştirin.
  5. Makine icat edilene kadar bekleyin.
  6. Zaman makinesini kullanarak geleceğe atlayın. 1YHz 128bit CPU satın aldıysanız 3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 ps, programı çalıştırmaya başladığınızda sonrasına geçin .
  7. ...?
  8. KAR !!!

... 1GHz CPU'dan 1 kat daha hızlı (ya da ikili önek kullanmayı tercih ederseniz) en az 10,783,127yıl alır .1,000,000,000,000,0001,125,899,906,842,624

Bu nedenle, hesaplamanın bitmesini beklemek yerine, evlerini kaybeden güvercinleri beslemek daha iyi olurdu çünkü diğer ngüvercinler evlerini aldı. :(

Veya 128 bit kuantum bilgisayarı icat edilene kadar bekleyebilirsiniz. O zaman programınızı makul bir süre içinde (belki de) kullanarak GUID'in benzersiz olmadığını kanıtlayabilirsiniz.


Bu cevapta süper kahraman referansı bekliyordum - posterle başarısız oldu: p - harika hiçbiri az.
IbrarMumtaz

4

begin = begin + new BigInteger((long)1)Start ++ yerine denediniz mi?


2
Kimse soruyu gerçekten cevaplayan cevaba oy vermedi: P
nawfal

4

Oluşturulan UUID sayısı Moore yasalarına uyarsa, öngörülebilir gelecekte GUID'in hiç bitmemesi izlenimi yanlıştır.

2 ^ 128 UUID ile, tüm UUID'lerin tükenmesinden önce sadece 18 ay * Log2 (2 ^ 128) ~ = 192 yıl sürecektir.

Ve inanıyorum ki (UUID'nin kitlesel olarak benimsenmesinden bu yana geçen birkaç yıl içinde hiçbir istatistiksel kanıt olmadan), UUID üretme hızımız Moore yasasının öngördüğünden daha hızlı artıyor. Başka bir deyişle, UUID kriziyle başa çıkmak zorunda kalana kadar muhtemelen 192 yıldan daha az zamanımız var, bu evrenin sonundan çok daha erken.

Ancak 2012 sonunda kesinlikle tükenmeyeceğimiz için, sorun hakkında endişelenmek için onu diğer türlere bırakacağız.


3

GUID üreten koddaki bir hatanın olasılığı, bir çarpışma oluşturan algoritmanın oranından çok daha yüksektir. GUID'leri test etmek için kodunuzdaki bir hatanın olasılığı daha da fazladır. Pes etmek.


2

Program, hataları da olsa, bir GUID'in benzersiz olmadığının kanıtıdır. Aksini kanıtlamaya çalışanlar bu noktayı kaçırıyorlar. Bu ifade, bazı GUID varyasyonlarının zayıf bir şekilde uygulandığını kanıtlamaktadır.

Bir GUID tanım gereği benzersiz değildir, tanım gereği oldukça benzersizdir. Az önce anlamını geliştirdiniz. Sürüme bağlı olarak, uygulayıcı (MS veya diğerleri), VM'lerin kullanımı, vb. (önceki yayındaki bağlantıya bakın)

Noktanızı kanıtlamak için 128 bitlik masanızı kısaltabilirsiniz. En iyi çözüm, tablonuzu kopyalarla kısaltmak için bir karma formül kullanmak ve ardından karma çarpıştığında ve buna göre bir GUID yeniden oluşturmak için tam değeri kullanmaktır. Farklı konumlardan koşuyorsanız, karma / tam anahtar çiftlerinizi merkezi bir konumda saklarsınız.

Ps: Hedef sadece farklı sayıda x değeri oluşturmaksa, bu genişlikte bir karma tablosu oluşturun ve karma değerini kontrol edin.


2

Burada şenlik ateşinde p ** s değil, ama aslında oluyor ve evet, bu adama verdiğiniz şaka anlıyorum, ama GUID sadece prensipte benzersiz, bu konuya çarptım çünkü bir hata var WP7 öykünücüsünde, yani her önyükleme yaptığında SAME GUID'i ilk çağrıldığında verir! Teoride, söz konusu GUI'yi yaratan bir sorun varsa, o zaman kopyalar alabilirsiniz.

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


1

Guid jenerasyonunun bir kısmı mevcut makinenin zamanına dayandığından, yinelenen bir Guid alma teorim:

  1. Windows'un temiz bir kurulumunu gerçekleştirin
  2. Windows açılırken saati 2010-01-01 12:00:00 olarak sıfırlayan bir başlangıç ​​komut dosyası oluşturun.
  3. Başlangıç ​​komut dosyasından hemen sonra, bir Guid oluşturmak için uygulamanızı tetikler.
  4. Sonraki Windows açılışlarında oluşabilecek küçük farklılıkları ortadan kaldırmak için bu Windows kurulumunu kopyalayın.
  5. Sabit sürücüyü bu görüntü ile yeniden görüntüye alın ve makineyi birkaç kez önyükleyin.

0

Benim için .. bir UUIDv1 oluşturmak için tek bir çekirdek için gereken zaman benzersiz olacağını garanti eder. Çok çekirdekli bir durumda bile, UUID jeneratörü belirli bir kaynağınız için aynı anda yalnızca bir UUID'nin oluşturulmasına izin veriyorsa (birden fazla kaynağın aynı UUID'leri tamamen kullanabileceğini unutmayın, ancak kaynak adresin doğal olarak adresinin bir parçası olduğundan) zaman damgası tükenene kadar size yetecek kadar UUID'ye sahip olacak. Bu noktada gerçekten umursadığınızdan şüpheliyim.


0

İşte size bir çözüm:

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

Not: Qt gerektirir, ancak yeterince uzun süre çalışmasına izin verirseniz bir tane bulabileceğini garanti ederim.

(Not: aslında, şimdi ona baktığımda, daha sonra üretilen iki çarpışmayı önleyen nesil algoritması hakkında bir şeyler olabilir - ama biraz şüpheliyim).


0

GUID'lerin benzersiz olmadığını kanıtlamanın tek çözümü, bir Dünya GUID Havuzu'na sahip olmak olacaktır. Her yerde bir GUID oluşturulduğunda, kuruluşa kaydedilmesi gerekir. Veya tüm GUID jeneratörlerinin otomatik olarak kaydetmesi gereken bir standardizasyon ekleyebiliriz ve bunun için aktif bir internet bağlantısına ihtiyaç duyarız!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.