GUID çakışmaları mümkün müdür?


128

Bağlı olduğu uygulamayı kullanan her kullanıcı için bir GUID kullanan SQL Server 2000'de bir veritabanı üzerinde çalışıyorum. Her nasılsa, iki kullanıcı aynı GUID'ye sahip oldu. Microsoft'un çarpışmalara neden olma olasılığı son derece düşük olan rastgele bir GUID oluşturmak için bir algoritma kullandığını biliyorum, ancak yine de bir çarpışma mümkün mü?


11
Herkes hayır diyor yanlış. 1 UniqueIdentifier'ı yarım milyondan daha az kayıt içeren bir veri kümesiyle zaten çarpıştım, MSSQL 2008 R2
Behrooz

2
@Behrooz Yikes. Arkadaşımız doğum günü paradoksu sayesinde imkansız değil, ancak tamamen rastgele v4 GUID'leri ile hala delicesine şanssız. Belki daha zayıf bir GUID oluşturma stratejisi kullanıyordunuz?
Craig Ringer

6
@Behrooz Wow. Bu şok edici şans.
Craig Zil

6
@Behrooz bu muhtemelen MSSQL'de kullanılan hatalı bir sözde rasgele sayıdır (yazılımlarının kalitesi göz önüne alındığında, jeneratörlerinde 32 bit tohum veya benzeri bir şey varsa şaşırmam). Matematik yalan söylemez. Bu olasılık o kadar küçüktür ki,% 99.9999999999 (ve çok sonra)% 99.9999999999 olabilir, ya MSSQL kılavuz oluşturucusu arızalıdır (veya GUID'leri oluşturmak için kullanılan sözde rastgele oluşturucu olabilir) veya bir hata yaptınız.
Alex

2
Tam şu anda hem sorunun hem de seçilen cevabın 128 puana sahip olmasını seviyorum. Tesadüf? 🤔
Caio Cunha

Yanıtlar:


127

Temelde hayır. Sanırım birisi veri tabanınızı karıştırdı. Kullandığınız GUID sürümüne bağlı olarak, değer ya benzersizdir (sürüm 1 GUID'ler gibi şeyler için) ya da hem benzersiz hem de öngörülemez (sürüm 4 GUID'ler gibi şeyler için). SQL Server'ın NEWID () işlevi için uygulaması 128 bitlik rastgele bir sayı kullanıyor gibi görünüyor, bu nedenle bir çarpışma olmayacak.

% 1'lik bir çarpışma şansı için, yaklaşık 2.600.000.000.000.000.000 GUID oluşturmanız gerekir .


3
Ben de öyle anladım, ama bunu göz ardı edemeyeceğimden emin olmak istedim. 8 yıllık bir yazılımda ne tür tuhaf hataların ortaya çıkabileceğini asla bilemezsiniz. :)
Jason Baker

6
Aslında bu artık doğru değil. V1 GUID'leri için doğruydu, ancak mevcut v4 olanlar için geçerli değildi. Daha fazla bilgi için en.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm adresine bakın .
Greg Beech

97
Aşağı oylama, çünkü prensipte (en ham haliyle), "GUID çarpışmaları mümkün mü?" Sorusuna "hayır" demekte yanılıyorsunuz. Bu çok mümkün. Olasılığı çok küçük ama mümkün. Bilgiçlik taslamaktan nefret ederim - ama SO tamamen özlü ve doğru olmakla ilgilidir.

13
% 1'lik sonucu elde etmek için wolfram alfa'ya "çöz [1-exp [- (n ^ 2 / (2 * 2 ^ 128))]> 0.01, n]" girin ... Bu sayı büyük gözükürken dikkat edin BİR uygulama bağlamında, kesinlikle tüm dünya için büyük değil. Yeryüzündeki her bilgisayar gerçek GUID'ler oluşturacaksa, her nanosaniyede bir GUID oluşturabileceklerini varsayarak yaklaşık bir saniye içinde% 1 olasılıkla bir çarpışmaya neden olurlar (ki bu bugünlerde muhtemelen oldukça gerçekçi). Dolayısıyla, veritabanı kimlikleriniz için GUID'ler kullanıyorsanız, bunlar benzersizdir. Dünyada yapılan her hesaplama için GUID'ler anında çarpışacak.
thesaint

11
'Hayır' demek mümkün değil ve ardından belirli bir miktar üretildiğinde çarpışma olma ihtimalinin% 1 olduğunu söylemek doğrudan çatışmalardır. Doğru yanıt Teorik olarak olmalıdır - evet, rastgele bir çarpışma olabilir. Bununla birlikte, çarpışma şansı istatistiksel olarak Dünya'ya çarpan, Dünya'dan seken ve sonraki bir saat içinde Dünya'ya ikinci kez çarpmak için Ay'dan geri dönen bir asteroidden daha düşüktür.
Baaleos

112

Temelde mümkün değiller! , şans astronomik olarak düşük .

Ama ... Dünyada tanıdığım, bir zamanlar GUID çarpışması olan tek kişi benim (evet!).

Ve bundan eminim ve bu bir hata değildi.

Nasıl oldu, Cep Bilgisayarda çalışan küçük bir uygulamada, bir işlemin sonunda oluşturulan bir GUID'ye sahip bir komutun verilmesi gerekir. Komut, sunucuda çalıştırıldıktan sonra, yürütme tarihiyle birlikte sunucudaki bir komut tablosunda saklandı. Hata ayıklarken bir gün modül komutunu verdim (yeni oluşturulan GUID eklenmiş olarak) ve hiçbir şey olmadı. Tekrar yaptım (aynı kılavuzla, çünkü kılavuz işlemin başlangıcında yalnızca bir kez oluşturuldu) ve tekrar ve hiçbir şey, sonunda komutun neden çalışmadığını bulmaya çalışıyorum, komut tablosunu kontrol ettim, ve mevcut GUID ile aynı GUID 3 hafta önce eklendi. Buna inanmadan, bir veritabanını 2 haftalık yedeklemeden geri yükledim ve rehber oradaydı. Kodu kontrol ettim, yeni kılavuz hiç şüphesiz yeni oluşturuldu.

Düzenleme: Bunun olma olasılığını büyük ölçüde artırabilecek bazı faktörler var, uygulama PocketPC öykünücüsünde çalışıyordu ve öykünücünün durum kaydetme özelliği var, bu da durum her geri yüklendiğinde yerel saatin de geri yüklendiği anlamına geliyor ve kılavuz dahili zamanlayıcıya dayanmaktadır .... ayrıca kompakt çerçeve için kılavuz oluşturma algoritması örneğin COM olana göre daha az eksiksiz olabilir ...


38
Upvoted. Durumu kaydet ve tekrar oynatma gerçekten yinelenen kılavuzlar oluşturacaktır.
Joshua

35
Muhtemelen olan şey bu "kötü" bir GUID uygulamasıydı. Teorik oran çok düşük, ama Pocket PC ?? Bu olasılıkları "olası olmayan, ancak olası" kategorisine taşıyan bir kestirmeden gitmediklerini kim söyleyebilir?
Dave Dopson

9
Bir şeyin olma olasılığının çok düşük olması, olmayacağı anlamına gelmez.
Renan

3
Yukarıda söylediğim gibi, bunun şansı o kadar azalıyor ki, bir hata yaptığınızı veya MSSQL'in hatalı bir PRNG kullandığını varsaymak güvenlidir ( en.wikipedia.org/wiki/Pseudorandom_number_generator ). Örneğin, bu PRNG'nin küçük boyutlu bir tohumla başlatılması muhtemeldir. Arızalı PRNG'ler nadir değildir (bkz. Schneier.com/paper-prngs.html ) - örneğin yakın zamanda Android SDK'da bir kusur keşfedildi - android-developers.blogspot.com/2013/08/… + usenix.org/conference/woot14 / workshop-program / Presentation /…
Alex

2
@Alex, hata, öykünücü saati de dahil olmak üzere tüm öykünücü görüntüsünü geri yükleyen Emülatörden "Durumu Kaydet ve Geri Yükle" idi. Bu nedenle, bir yıl boyunca yapılan binlerce Geri Yükleme işleminin ardından, bir kılavuzlu çarpışma meydana geldi. Haklısın bir hata var!
Pop Catalin

34

Teorik olarak mümkündür, ancak 3.4E38 olası sayılarla, bir yılda onlarca trilyon GUID oluşturursanız, bir kopya alma şansı 0.00000000006'dır ( Kaynak ).

İki kullanıcı aynı GUID ile sonuçlanırsa, programda verilerin kopyalanmasına veya paylaşılmasına neden olan bir hata olduğuna bahse girerim.


"ancak 3.4E38 olası sayılarla" - hayır. Aynı makinede hemen hemen aynı anda oluşturulan iki GUID, son derece benzer GUID'lerle sonuçlanır.
Kirk Strauser

4
Bu, GUID'in nasıl oluşturulduğuna bağlı olacaktır ve CPU zamanına veya milisaniyeye dayalı bazı uygulamalar, (umarız) hangi hesaplamayı temel alırsa onu abartır, böylece milisaniyelerden oluşan iki GUID büyük bir fark yaratır.
Dalin Seivewright

4
Bir makinedeki 1'den fazla işlemci ile, eğer bir kılavuz zamana ve mac adresine dayanıyorsa, o zaman her bir çekirdek aynı anda aynı kılavuzu verebilir.
AndyM

12
Ben eminim herhangi nezih GUID uygulama olmaz
Guillaume86

1
@MatthewLock Doğum paradoksu kaynakta ele alınmıştır. Bağlantıyı kontrol edin.
Zero3

21

İlk önce iki GUID'in çarpışma şansına bakalım. Diğer yanıtların da belirttiği gibi, doğum günü paradoksu nedeniyle 2 ^ 128'de 1 (10 ^ 38) değildir , bu da iki GUID'in çarpışması olasılığının% 50 olması için 2 ^ 64'te 1 (10 ^ 19) çok daha küçük. Bununla birlikte, bu hala çok büyük bir sayıdır ve bu nedenle, makul sayıda GUID kullandığınızı varsayarsak, çarpışma olasılığı düşüktür.

Birçok insanın da inandığı gibi GUID'lerin zaman damgası veya MAC adresi içermediğini de unutmayın. Bu, v1 GUID'leri için doğruydu, ancak artık v4 GUID'leri kullanılıyor, bunlar sadece sözde rastgele bir sayıdır, bu da çarpışma olasılığının tartışmalı olarak daha yüksek olduğu anlamına gelir çünkü artık bir zamana ve bir makineye özgü değildir.

Yani esasen cevap evet, çarpışmalar mümkündür. Ama pek olası değiller.

Düzenleme: 2 ^ 64 olarak düzeltildi


2
Tüm gerçeklerinize katılıyorum ama matematiğinize dikkat edin. Herhangi iki GUID'in çakışması olasılığının 10 ^ 19'da 1 olduğunu söylemek, kümede kaç GUID olduğuna bağlıdır. Bu şans için ~ 2 ^ 32 GUID'e ihtiyacınız vardır, bu nedenle neredeyse tüm gerçek dünya senaryolarında olasılıklar çok daha düşüktür.
DocMax

1
Sen bir yazım hatası var 1 in 10^64 (10^19)olmam gerektiğini düşünüyorum 1 in 2^64 (10^19). Ayrıca doğum günü paradoksunun sadece 2 sayı için geçerli olduğunu düşündüğünüzde çok kafam karıştı. En.wikipedia.org/wiki/Birthday_paradox'a baktığınızı varsayıyorum . Tablo, belirli bir kopya olasılığı için kaç rehbere ihtiyacınız olduğunu gösterir. Bu tablodan 10 ^ 18'de 1 olasılık 2.6 * 10 ^ 10 kılavuz gerektirir, sadece iki GUID'ye yakın bir şey değildir.
Tony Lee

Bir nokta - v1 kılavuzları hala yaygın olarak kullanılmaktadır ve arzu edilen özelliklere sahip oldukları için özellikle veritabanlarında MAC adresine güvenmektedir. UuidCreateSequential'a ve SQL Server sarmalayıcısı NewSequentialID'ye bakın ( msdn.microsoft.com/en-us/library/windows/desktop/… ).
EBarr

18

İki rastgele GUID'in çarpışma olasılığı (10 ^ 38'de ~ 1), bozuk bir TCP / IP paketini (10 ^ 10'da ~ 1) algılamama olasılığından daha düşüktür. http://wwwse.inf.tu-dresden.de/data/courses/SE1/SE1-2004-lec12.pdf , sayfa 11. Bu aynı zamanda disk sürücüleri, cd sürücüleri vb. için de geçerlidir ...

GUID'ler istatistiksel olarak benzersizdir ve veritabanından okuduğunuz veriler yalnızca istatistiksel olarak doğrudur.


10 ^ 28 paketin 1'den azı bozuk olduğundan ağımı zırhlayamayacağıma emin misin?
Joshua

13

Occam'ın tıraş makinesini bu durumda iyi bir rehber olarak düşünürdüm . Bir GUID çarpışmanızın olması inanılmaz derecede düşük bir ihtimaldir. Bir hatanız olması veya verilerinizle uğraşması çok daha olasıdır.


1
Aslında bu durumda Occam'ın tıraş bıçağı hiç de iyi bir rehber değil! Occam's Razor, en az varsayıma sahip durumun büyük olasılıkla doğru olduğunu söylüyor. Bu durumda GUID çarpışması durumu aslında çok daha basittir, ancak Occam's Razor, vakalardan birinin inanılmaz derecede olası olmadığını zaten bildiğimiz böyle bir durum için geçerli değildir.
lockstock

11

Wikipedia'nın Küresel Olarak Benzersiz Tanımlayıcı makalesine bakın. GUID oluşturmanın birkaç yolu vardır. Görünüşe göre eski (?) Yöntem Mac adresini kullanıyordu, çok kısa bir birime kadar bir zaman damgası ve benzersiz bir sayaç (aynı bilgisayarda hızlı nesilleri yönetmek için), bu yüzden onları kopyalamak neredeyse imkansız. Ancak bu GUID'ler, kullanıcıları izlemek için kullanılabilecekleri için bırakıldı ...

Microsoft tarafından kullanılan yeni algoritmadan emin değilim (makale bir dizi GUID'nin tahmin edilebileceğini söylüyor, artık zaman damgası kullanmıyorlar gibi görünüyor? Yukarıda bağlantısı verilen Microsoft makalesi başka bir şey söylüyor ...).

Şimdi, GUID'ler adlarına göre küresel olarak benzersiz olacak şekilde dikkatle tasarlanmıştır, bu nedenle imkansız veya çok çok çok düşük olasılık riskini alacağım. Başka yere bakardım.





9

Yinelenen MAC adreslerine sahip ethernet kartlarına sahip iki Win95 makinesi, özellikle, örneğin, binada güç kesilirse ve ikisi de tam olarak aynı anda önyüklenirse, sıkı şekilde kontrol edilen koşullar altında yinelenen GUIDS yayınlayacaktır.


İki farklı makinenin aynı ethernet MAC adresine sahip olması yaygın mıdır?
Dave Lucre

@DaveLucre: Hayır, ancak olaylar kaydedildi.
Joshua

Bunun nasıl ortaya çıktığını gerçekten merak ediyorum. Her NIC için rastgele bir MAC oluşturan VM'lerde daha olası mıdır? Yinelenen MAC'larla üretilen fiziksel NIC'leri hiç duymadım! Mümkünse işlere büyük bir anahtar fırlatıyor!
Dave Lucre

Vaov! @Joshua bağlantısı için teşekkürler! Ne kadar büyük bir berbat!
Dave Lucre

@DaveLucre TÜMÜNÜN aynı MAC ile üretildiği bazı çok ucuz USB NIC'ler kullandım. Ama elbette bunun rastgeleliğin matematiği ve üreticinin tembelliği ile hiçbir ilgisi yok.
rudolfbyker

5

Bunun önsözünü "Ben bir ağ kurucusu değilim, bu yüzden aşağıda tamamen tutarsız cümleler kurabilirim."

Illinois Eyalet Üniversitesi'nde çalışırken, farklı zamanlarda sipariş edilen iki Dell masaüstü bilgisayarımız vardı. İlkini ağa koyduk ama ikincisini ağa koymaya çalıştığımızda çılgın hatalar almaya başladık. Çok fazla sorun giderme işleminden sonra, her iki makinenin de aynı GUID'yi ürettiği belirlendi (tam olarak ne için olduğundan emin değilim, ancak her ikisini de ağda kullanılamaz hale getirdi). Dell aslında her iki makineyi de kusurlu olarak değiştirdi.


3
Özellikle GUID idi. Ağa katıldıklarında makineler tarafından oluşturulan GUID ile bir ilgisi vardı. Dell'in makineleri değiştirmesi birkaç hafta sürdü, çünkü GUID'lerin aynı olmasının imkansız olduğunu söylediler. Sorunu yeniden oluşturabildik, Dell makineleri geri aldı ve aynı sonuçları ağlarında da üretebildik. Her iki makineyi de değiştirdiler. Dediğim gibi, ben bir ağ uzmanı değilim, ancak bunun GUID'lerle ilgili bir sorun olduğunu özellikle hatırlıyorum.
John Kraft

5

İnsanların, GUID'lerin sihirli ve benzersiz olmalarının garantili olduğu iyi hissettiren yanıtını sevdiklerini biliyorum, ancak gerçekte çoğu GUID yalnızca 121 bitlik rastgele sayılardır (bitlerin yedisi biçimlendirmede boşa harcanır). Büyük bir rastgele sayı kullanmakta kendinizi rahat hissetmezseniz, bir GUID kullanmakta kendinizi rahat hissetmemelisiniz.


11
Ayrıca ağları kullanmamanızı tavsiye ederiz. Veya bilgisayarlar. Eşlik bitleri yalnızca bu kadarını yapabilir!
Rushyo

Sen yanlış anladın. Bu yazıda söylemeye çalıştığım iki şey var: 1) Büyük bir rastgele sayıya ihtiyacınız varsa, büyük bir rastgele sayı kullanın. Bir GUID'yi büyük bir rasgele sayı olarak kullanmak gereksiz yere yanıltıcıdır. (2)
Rick Yorgason

4
Ben tamamen farkındayım. "Büyük bir rastgele sayı kullanmaktan rahatsızlık duymazsan" dedin. ancak GUID'ler o kadar benzersizdir ki, bir bilgisayardaki hemen hemen her şeyin daha rastgele olduğunu görürsünüz, hatta aldığınız işlemler bile. Bir ucube bellek arızasının kimlik sütununuzu kırma ihtimali, (gerçek) bir GUID çarpışmasının meydana gelmesinden daha fazladır. Onlar hakkında 'rahatsız' hissetmemelisiniz. Senaryo için ideal değillerse sorun değil - ancak özel bir dikkat gerektirmiyorlar.
Rushyo

3
Sanırım bu hiçbir yere gitmiyor, ancak insanların size açıklamaya çalıştıkları şey, ağ kartları veya sabit sürücüler gibi yaygın donanımlardaki hata algılama mekanizmalarının, bir GUID çarpışması alma ihtimalinizden daha büyük bir hata tespit etmeme şansı olan algoritmalar kullandığıdır. bunlara güveniyorsanız, GUID'lere de güvenebilirsiniz
Guillaume86

1
@Rick, numaranızın ne kadar büyük olduğuna bağlı. Kesinlikle 4 byte int veya 8 byte bigint ile değil. GUID = 16 bayt, bu nedenle aynı 2 ^ 128 olası kombinasyonu elde etmek için özel bir 16 baytlık büyük sayı uygulamasına ihtiyacınız olacaktır. 'Normal' int veya bigint rasgele sayılar kullanılarak Yani genel olarak konuşmak gerekirse, bir GUID ile çakışması olasılığı olan düşük (her biri için rastgele algo düşünceleri dışarıda bırakarak).
Wim Hollebrandse

3

Bir GUID oluşturmak için kullanılan kodda bir hata olabilir mi? Evet, elbette olabilir. Ancak yanıt, bir derleyici hatası için olacağının aynısıdır - kendi kodunuz büyük olasılıkla hatalı olma olasılığı yüksektir, bu yüzden önce oraya bakın.


2

Elbette mümkün .... Muhtemel mi? Muhtemel değil, ama mümkün.

Unutmayın, aynı makine her GUID'yi (sunucu) oluşturuyor, bu nedenle makineye özgü bilgilere dayanan "rastlantısallığın" büyük bir kısmı kayboluyor.


1

Sırf sırıtmak için, aşağıdaki komut dosyasını deneyin ... (SQL 2005'te çalışıyor, 2000'den emin değilim)

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

Bunu tekrar tekrar çalıştırmak (bir saniyeden daha az sürer), ÇOK kısa bir zaman aralığı olsa bile, ilk seçimden oldukça geniş bir aralık üretir. Şimdiye kadar ikinci seçim hiçbir şey üretmedi.


1
% 50 kopya şansına sahip olmak için sayacın sonunda 15 sıfır daha gerekir. Ama Pete aşkına yapma!
Jim Birchall

0

Kullanıcıların ağ kartlarına sahip farklı makineleri varsa imkansızdır ve olmasa bile bu hala son derece marjinal neredeyse teorik bir risktir.

Şahsen ben başka bir yere bakardım, çünkü bu bir GUID çatışmasından ziyade bir hata olabilir ...

Tabii ki, GUID'yi kısaltmak için bitleri kesmemenizi sağlar.


GUID'ler Sunucu üzerinde oluşturulacak ve böylece kullanıcının ağ kartları devreye girmeyecektir.
Tom Ritter

0

Elbette mümkün ve hatta muhtemelen. Her GUID, olası sayı uzayının rasgele bir bölümünde olduğu gibi değildir. İki iş parçacığının aynı anda bir tane oluşturmaya çalışması durumunda, etrafında bir semafor bulunan bir tür merkezi GUID işlevi engellenirse, aynı değere sahip olabilirler.


0

Bunları aşağıdaki gibi bir şey aracılığıyla oluşturuyorsanız, GUID çarpışmalarıyla karşılaşmanız pek olası değildir. NEWID() SQL Server'daki işlev (diğer yanıtların vurguladığı gibi elbette mümkün olsa da) . İşaret etmedikleri bir şey, JavaScript'te GUID'leri vahşi tarayıcılarda oluşturuyorsanız, çarpışmalarla karşılaşmanızın oldukça muhtemel olmasıdır. Sadece RNG'de farklı tarayıcılarda bazen sorunlar olmakla kalmayıp, aynı zamanda Google örümceklerinin bu gibi işlevlerin sonuçlarını önbelleğe aldığını ve aynı GUID'yi tekrar tekrar sistemimize ilettiği sorunlarla karşılaştım.

Daha fazla ayrıntı için buradaki çeşitli yanıtlara bakın:

JavaScript'te UUID'ler oluştururken meydana gelen çarpışmalar?

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.