UUID çarpışmaları [kapalı]


33

Kullandığımız rasgele sayı üreticilerinin gerçekten rastgele olmadığı ve aynı kodu çalıştıran düzinelerce veya yüzlerce aynı makineye sahip olabileceğimiz göz önüne alındığında, UUID çarpışma olasılığı konusunda, özellikle de sürüm 4 (rastgele) UUID'lerle ilgili gerçek bir araştırma yapan var mı? UUID oluşturma?

İş arkadaşlarım UUID çarpışmasının test edilmesinin tamamen zaman kaybı olduğunu düşünüyor, ancak veritabanından yinelenen önemli bir istisna yakalamak için her zaman kod koydum ve yeniden yeni bir UUID ile tekrar dene. Ancak, eğer UUID başka bir işlemden gelir ve gerçek bir nesneye atıfta bulunursa bu sorunu çözmeyecektir.


4
Bu soru, Temel Google aramasını gösterdiği gibi Stack Overflow: stackoverflow.com/questions/3038023/…
Arseni Mourzenko

3
Bu soru, kesinlikle bir sürüm 4 (rastgele) DEĞİL olan SQL * Server'da kullanılan belirli algoritmalar ile ilgilidir. Özellikle sürüm 4 hakkında soruyorum.
Paul Tomblin,

SQL Server'ın NEWID()işlevin uygulanmasının rastgele olmadığını mı söylüyorsunuz? Öyleyse, böyle bir iddiayı destekleyecek herhangi bir kaynağınız var mı? Çıkışı açıkça bana v4 UUID'lere benziyor. NEWSEQUENTIALID()kararının tamamen rastlantısal olmadığı kararlaştırılmıştır, ancak amacı budur : Dizin anahtarları olarak iyi çalışan UUID'leri (en azından UUID'lerin yapabildiği gibi) üretmek.
12'de CVn

1
NEWID () 'nin mac adresinin bazı bitlerini içerdiğini belirten, V4'ü V1 veya V2 UUID yapan, bağlantılı sorunun cevabına gidiyorum.
Paul Tomblin

2
Bu soru konu dışı gibi görünüyor çünkü bu konu zaten internette, kitaplarda ve özellikle StackOverflow'ta ad-nauseum hakkında tartışılan bir konu hakkında

Yanıtlar:


18

Vikipedi'nin bazı ayrıntıları var:

http://en.wikipedia.org/wiki/Universally_unique_identifier

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

Fakat olasılık, sadece bitlerin tamamen rasgele olması durumunda geçerlidir. Bununla birlikte, diğer cevaba bağlı RFC http://tools.ietf.org/html/rfc4122#page-14 , sürüm 4 için bunu tanımlar:

"4.4. [...] Sürüm 4 UUID, UUID'leri gerçekten rasgele veya sözde rasgele sayılardan oluşturmak içindir. [...] Diğer tüm bitleri rastgele (veya sözde rasgele) seçilen değerlere ayarlayın."

Bu hemen hemen xkcd rasgele üretecinden http://xkcd.com/221/ adresinden kuantum gürültüsü kullanan bir donanıma kadar her şeyi sağlar . RFC'deki güvenlik hususları:

"6. Çeşitli ana bilgisayarlarda UUID üreten dağıtılmış uygulamalar, tüm ana bilgisayarlarda rastgele sayı kaynağına güvenmeye istekli olmalıdır. Bu mümkün değilse, ad alanı değişkeni kullanılmalıdır."

Bunu şu şekilde okudum: Kendi başınasın. Kendi uygulamanızdaki rastgele üreteçten sorumlusunuz, fakat bu ve başka her şey güvene dayanıyor. Seçtiğiniz rastgele jeneratörü doğru bir şekilde anlama ve kullanma yeteneğinize güvenmiyorsanız, çarpışmaları kontrol etmek iyi bir fikirdir. Diğer işlemlerin programlayıcısına güvenmiyorsanız, çarpışmaları kontrol edin veya farklı bir UUID sürümü kullanın.


11

Bir çarpışma olup olmadığını kesinlikle saptamalısınız ve gerçekleşirse uygulamanızın bir istisna atması gerekir. Örneğin, UUID veritabanında birincil anahtar olarak kullanılıyorsa, çarpışan bir kimlik eklerken veritabanı bir hata atmalıdır.

Ancak, bir çarpışma durumunda yeni bir UUID oluşturmak için kod yazmanın ve tekrar zaman kaybı olmaya çalışıldığına inanıyorum. Bir çarpışmanın meydana gelme şansı o kadar küçüktür ki, bir istisna atmak, onunla başa çıkmanın tamamen makul bir yoludur.

Unutmayın, yalnızca kodu yazmak kendi zamanınızın boşa harcanması değildir, aynı zamanda kodu daha karmaşık hale getirir, bir sonraki kişinin okumasını zorlaştırır, neredeyse hiç kazanç sağlamaz.


2
UUID'niz yalnızca rastgele oluşturucunuz kadar iyidir. Çok ( çok ) fakir bir çarpışma ile sadece gerçekleşmekle kalmaz, kaçınılmazdır. Belki de üretim zamanında çiftleri kontrol etmenin gerçekten de fazlaca ümit edilmeyeceği, ancak durumun ortaya çıkabileceğini ve bence isteyecek çok fazla şey olmadığını beklediğini söyledi. Bazı etki alanlarında (örneğin sağlık hizmeti), bu gibi durumları yakalayan bir kodun gerekli olduğunu düşünüyorum (belki de veritabanında çarpışma algılama gibi). asla gerçekleşmeyen durumları ayıklamak için ne kadar zaman harcadığımı şaşırırsınız.
Newtopian

1
Sanırım kendimi netleştirmedim. Daha açık olması için cevabı güncelledim.
Pete

7

Bu çok iyi bir soru. Her yerde UUID kullanmak için aceleyle yeterince düşünülmüş olduğuna inanmıyorum. Hiç sağlam bir araştırma bulamadım.

Bir öneri: çok dikkatli bir şekilde burada bas ve şifrelemeni iyi bil. 128 bitlik bir UUID kullanıyorsanız, 'doğum günü etkisi' bize, her bir tuşta 128 bit entropi olması koşuluyla , bir çarpışmanın yaklaşık 2 ^ 64 anahtar oluşturduktan sonra olduğunu söyler .

Durumun böyle olmasını sağlamak aslında oldukça zor. Gerçek rassallık (a) radyoaktif bozunma (b) rastgele arka plan radyo gürültüsünden, (c) dikkatli bir şekilde seçilen bir elektronik gürültü, örneğin ters-taraflı bir Zener diyotundan alınmadıkça, sıklıkla kontamine olan rasgele arka plan radyo gürültüsünden üretilebilir. (Sonuncuyla oynadım ve bir çekicilik gibi çalışıyor, BTW).

Kullanıcı 2 ^ 64 (yaklaşık 10 ^ 19) tuşa yaklaşan bir şey üretmediği ve hepsinin birbirine karşı kontrol ettiği sürece, "Bunu bir yıl boyunca kullanmadım" gibi bildirimlere güvenmezdim. önemsiz egzersiz.

Sorun bu. Diyelim ki sadece 100 bit entropiye sahipsin, anahtarlarınızı diğer tüm anahtarlarla karşılaştırırken herkesin ortak bir anahtar boşlukta ürettiği. Yani, yaklaşık 2 ^ 50'de çarpışmaları görmeye başlayacaksınız. yaklaşık 10 ^ 15 tuş. Veritabanınızı yalnızca 1000 milyar anahtarla doldurduysanız bir çarpışma görme şansınız hala göz ardı edilebilir. Ve kontrol etmezseniz, daha sonra peta-satır boyutundaki veritabanınıza sürünen beklenmedik hatalar alırsınız. Bu zor ısırır.

Bu tür UUID'lerin üretilmesinde çok sayıda yaklaşım olduğu gerçeği, kaygılı bir anlık spazmaya yol açmalıdır. Çok az sayıda jeneratörün tip 4 UUID için yeterli entropiye sahip 'gerçekten rastgele' işlemleri kullandığını fark ettiğinizde , jeneratörün entropi içeriğini dikkatlice incelemediğiniz sürece aşırı derecede endişe duymalısınız. (Çoğu insan bunu yapmaz, hatta nasıl yapılacağını bile bilmez; DieHarder süiti ile başlayabilirsiniz). Sahte rasgele sayı oluşumunu gerçek rasgele sayı oluşturma ile karıştırmayın.

İçine koyduğun entropinin, sahip olduğun entropi olduğunu fark etmen çok önemli, ve şifreli bir işlev uygulayarak anahtarı bozmak entropiyi değiştirmiyor. Eğer tüm alanım 0 ve 1 rakamını içeriyorsa entropi içeriğinin aşağıdaki iki dizeninkiyle aynı olduğu sezgisel olarak anlaşılmayabilir: "Bu gerçekten çok karmaşık bir dizedir 293290729382832 * ! @@ # & ^% $$) ,. m} "ve" Ve ŞİMDİ TAMAMEN FARKLI BİR ŞEY İÇİN ". Hala sadece iki seçenek var.

Rastgele olma, haklı olmak için zordur ve basitçe "uzmanların baktığı için bu nedenle tamam" olduğuna inanmak yeterli olmayabilir. Uzman kriptografları (ve gerçekten de yeteri kadar az sayıda var) sık sık yanlış anladıklarını itiraf eden ilk kişilerdir. Heartbleed, DigiNotar vb.

Bence Paul Tomblin uygun bir önlem alıyor. Benim 2c.


6

Sorun şu ki, eğer bir "Rastgele sayı üreteci" kullanıyorsanız ve bu üreteçin ne kadar rastgele olduğunu bilmiyorsanız, çarpışma olasılığı aslında bilinmiyor. Eğer rastgele sayı üreteçleri bir şekilde ilişkilendirilirse, çarpışma olasılığı çarpıcı bir şekilde artabilir - muhtemelen birçok emir veya büyüklük.

Çok küçük bir çarpışma olasılığına sahip olsanız bile, temel bir probleminiz var: Olasılık 0 değil. Bu, bir çarpışmanın SONRA gerçekleşeceği anlamına gelir, çok sık gerçekleşmezler.

UUID'leri ne kadar sık ​​üretir ve kullanırsanız, çarpışma o kadar erken görülür. (yılda 1 üretmek, diğer her şey eşit olmak üzere saniyede bir milyon oluşturmaktan daha uzun bekleme süresi anlamına gelir).

Bu olasılık sonluysa, bilinmiyorsa ve çok fazla UUID kullanıyorsanız, bir çarpışmanın sonuçlarını düşünmeniz gerekir. Bir istisna atmak ve bir iş başvurusunu kapatmak kabul edilebilir değilse, o zaman bunu yapmayın! (Kafamın üstünden örnekler: "Bir kütüphane kontrolünü güncellerken ortasındaki web sunucusunu kapatmanız sorun değil ... sık sık olmaz" ve "Ortasındaki bordro sistemini kapatmanız tamam maaş koşulu yapıyorum ". Bu kararlar kariyer sınırlayıcı hamleler olabilir.)

Yine de uygulamanıza bağlı olarak, daha kötü bir durum olabilir. Eğer bir UUID'nin varlığını test ederseniz (yani, bir arama yapın) ve daha sonra orada bulunmamışsa, yapılacak ortak bir şey olan yeni bir tane yaparsanız, o zaman kayıtları bağladığınızı veya ilişki kurduğunuzu görebilirsiniz. , aslında bir UUID aracılığıyla birbirine bağlanması gerekmeyen 2 şeyi taktığınızda. Bu, bir istisna atmanın hiçbir şeyi çözmeyeceği ve bir yerde yaratılan algılanamayan bir karmaşanın olduğu bir şeydir. Bu bilgi sızıntısına neden olan ve çok utanç verici olabilecek bir şeydir. (örn: Bankanıza giriş yapın ve birinin hesabının bakiyesini görebileceğinizi görün! Kötü!)

Özet: UUID'lerin kullanım şeklini ve bir çarpışmanın sonuçlarını düşünmelisin. Bu çarpışmaları algılamaya ve önlemeye, çarpışma durumunda basit bir işlem yapmanıza veya hiçbir şey yapmamaya dikkat etmeniz gerektiğini belirler. Basit, tek, hepsine uyan bir çözüm bazı durumlarda uygunsuz olabilir.


2
"Çarpışma olasılığı 0" DEĞİL "" Herhangi bir sonlu uzunluk dizisi bu özelliğe sahiptir. Mükemmel rasgele bir v4 UUID ile bile, bir kez 2 ^ 122 benzersiz UUID (128 bit eksi 4 bit sürüm eksi 2 ayrılmış bit) oluşturduktan sonra, bir sonraki çarpışma olacağı garanti edilir. Büyük olasılıkla bundan daha erken bir çarpışmaya vuracaksınız. Asıl soru, 5e36 tekrarı gibi bir şeyden sonra bir çarpışmanın bir sorun olup olmadığı ve özünde de belirtildiği gibi, genel olarak cevaplanamayan (her bir özel durumda cevap vermek açık olsa da).
Ocak'ta CVn

Tabii ki. Bu bariz bir ifadeydi (ama yine de tekrarlayan ayılar). Sorun, rasgele sayı üreticilerinin ne kadar korelasyon gösterdiğidir. Bu anlamlı çarpışma olasılığını (^ 2 büyük) artırmak, ama ne kadar bir yapmadıkça bunu bilemezsiniz şeydir belki çok kazma, araştırma veya hesaplama. Çarpışma olasılığının, en iyi değerden önemli ölçüde daha kötü olduğu varsayılırsa, muhtemelen ihtiyatlıdır. Ondan sonra ... sonra sonuçlarını düşünmelisin.
Çabuk_ancak

0

İlgili iki konu var:

  1. Kullanılan rasgele sayı üreteçlerinin kalitesi.

  2. Üretilebilecek UUID miktarı.

Bir "rastgele" UUID'de 122 rastgele bit bulunur. Mükemmel rastlantısallık varsayarsak, ilk çarpışmayı yaklaşık 2 ^ 61 UUID'de bekleyebilirsiniz (2 ^ 122'nin karekökü). Bu dünyadaki herkes saniyede bir UUID üretecekti, bu yılda 10.000.000.000 * 365 * 24 * 60 * 60 = 315360000000000000 UUID, yani 2 ^ 58'e oldukça yakındı. Yani, birkaç yıl sonra ilk çarpışmaları alırsınız. Uygulamanız bu sayıların yakınında bir yere ulaşmazsa, rastgele jeneratörünüz iyi kalitede ise çarpışma elde edemeyeceğinizden emin olabilirsiniz.

Rastgele sayı üreteci hakkında konuşmak: Standart C kütüphaneleri jeneratörlerini (doğrudan, dolaylı veya benzer jeneratörler) kullanıyorsanız, muhtemelen onları zamanla tohumlayacaksanız, çarpıksınız. Bunlar çarpışmaları önlemek için yeterli entropi kullanamazlar. Bununla birlikte, Linux kullanıyorsanız, 16 bayt veriyi okuyunuz /dev/urandom: Bu, bazı gerçek rastgele olaylara erişimi olan, çekirdeğin karıştırdığı bir entropi havuzunu çizer. Genellikle UUID'leri gerçekten oluşturmadığınız sürece, önyükleme sırasında gerçekten erken, /dev/urandomgerçek bir rasgele kaynak gibi davranmalıdır.


-1

Bir keresinde 10 milyon UUID-s üreten oldukça basit (kaba kuvvet) bir program kullanarak test ettim ve çarpışma yaşamamıştım.

UUID RFC UUID (sözde) rasgele sayı sadece bir demet olmadığını söylüyor.


1
Benim sorduğum olan sürüm 4, neredeyse hepsinde tamamen aynı olacak 6 bit dışında, rastgele sayılardan oluşan bir demet.
Paul Tomblin,

8
10 milyon kova bile bir damla bile değil. Sadece 3E30'da bir çarpışma olasılığı var. Eğer bir tane bulursanız, acele etmenizi ve her çekilişe bir bilet almanızı tavsiye ederdim!
Ross Patterson

@RossPatterson, özellikle merak ettiğim şey, aynı donanımdaki aynı psuedo-rasgele algoritmayı kullanan birkaç yüz bilgisayarınız varsa, çarpışma olasılığını önemli ölçüde arttırıyor. Ben olacağından şüpheleniyorum.
Paul Tomblin,

1
@Paul - Sadece ilk tohumlama işleminde yetersiz entropi olup olmadığını düşünürdüm - örneğin tohum yalnızca günün zamanından üretildiyse ve tüm makineleriniz aynı anda çok yakın bir zamanda başladıysa. Tohumlamanın bu kadar zayıf olduğundan şüpheliyim - tabii ki her makine için benzersiz olan donanım seri numaralarının kullanılması bile mümkün.
Steve314,

1
Ne yazık ki, tohumlama çok zayıf olabilir. Linux sistemleri PRNG'yi oldukça rastgele kaynaklardan (cihaz sürücüsü faaliyeti vb. ) Ayırma konusunda düşkündür , ancak diğer ortamlarda standart, yakın zaman senkronizasyonunda yeterli makineyle sorun olabilen mevcut zaman damgasını kullanmaktır.
Ross Patterson,
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.