Benzersiz rastgele girişlere güvenmek kabul edilebilir?


42

Bir ağ protokolü uyguluyorum ve paketlerin benzersiz tanımlayıcıları olmasını istiyorum. Şimdiye kadar, rastgele 32-bit tamsayılar üretiyorum ve bunun astronomik olarak bir program / bağlantının ömrü boyunca bir çarpışma olamayacağının muhtemel olduğunu farz ediyorum. Bu, genel olarak üretim kodunda kabul edilebilir bir uygulama olarak mı kabul edilir yoksa çarpışmaları önlemek için daha karmaşık bir sistem mi geliştirmeli?


47
Neden sıralı bir tamsayı kullanmak onu kesmeyecek?
whatsisname,

20
Neden sadece artan bir int kullanmıyorsun? Tanımladığınız benzersiz özelliklere sahip olacak şekilde tasarlanan GUID'ler , 32 değil, 128 bit boyutundadır.
Robert Harvey

21
Alternatif olarak, bağlı her bilgisayara bir kanal numarası atayın ve artan bir sıra kimliği kullanın. Birleştirilmiş iki sayı (yüksek sıralı bitleri alan kanal numarasıyla birlikte) yeni benzersiz kimliğiniz olur.
Robert Harvey,

27
Eğer "rasgele sayı üreteciniz" belirli bir numaranın diğer her numara üretilinceye kadar tekrarlanmayacağını garanti ederse, çok zayıf bir rasgele sayı üretecidir! Aynı mantıkla, bozuk para fırlatmanın tek olası "rastgele" dizisi HTHTHTHTHT olacaktır ....
alephzero

17
“Paketlerin benzersiz tanımlayıcılara sahip olmasını istiyorum” Bu gereksinimin ihlal edilmesinin sonucu nedir? Benzersiz tanımlayıcılara ihtiyacınız varsa , kelimenin tam anlamıyla okunması halinde tanımlayıcıları dolduran merkezi bir sisteme sahip olmalısınız (MAC'lerin bireysel ağ kartı şirketlerine nasıl atandığı gibi). Büyük olasılıkla "gereksinim" in daha yumuşak bir tanımına sahipsiniz. Bu yumuşaklık seviyesinin anlaşılması aldığınız cevapları büyük ölçüde değiştirecektir.
Cort Ammon

Yanıtlar:


142

Doğum günü paradoksuna dikkat et .

Varsayalım ki, N büyüklüğünden (durumunuzda N = 2 ^ 32) bir rasgele değerler dizisi (tek tip, bağımsız olarak) oluşturduğunuzu varsayalım.

Daha sonra, doğum günü paradoksunun temel kuralı, bir kere sqrt (N) değerlerini oluşturduğunuzda, bir çarpışma meydana gelme ihtimalinin en az% 50 şansı olduğunu, yani oluşturulan sıra.

N = 2 ^ 32 için, sqrt (N) = 2 ^ 16 = 65536. Yani yaklaşık 65k tanımlayıcı oluşturduktan sonra, ikisinin çarpışmamasından daha büyük olasılıkla çarpışması olasıdır! Saniyede bir tanımlayıcı oluşturursanız, bu bir günden daha kısa bir sürede olur; Söylemeye gerek yok, birçok ağ protokolü bundan daha hızlı çalışır.


11
+1. Son işimde, ortaklarımızdan biri bu yaklaşımı rastgele tanımlayıcılar üretmek için kullandı (ağ paketleri için değil, nihayetinde son müşteriler tarafından oluşturulan paylaşılan bir iş nesnesi için). Verileri buna göz atarak sorguladığımda, ortalama olarak, her gün iki ya da üç çift kopya olduğunu buldum. (Neyse ki, bu sadece eğer çiftler birbirlerinin dört saat içinde yaratıldıysa, ki bunlar biraz daha az oldu. Ancak yine de.)
ruakh

6
(matematiği oluşturmak için buraya tıklayın) Buna değer, $ \ sqrt {N} $ yaklaşımı sabit bir faktöre kadar doğrudur; $ N = 2 ^ {32} $ için gerçek eşik 77164'tür, çünkü $ n $ 'ın en küçük değeri $ \ prod_ {k = 1} ^ {n-1} (1 - k / N) olacak şekilde <1 / 2. $
wchargin

4
@wchargin: Olasılık 0.5 ile ilgili sihirli bir şey yok; kayda değer olan şey, artan N ile göreceli olarak daha hızlı artmasıdır. 32 bitlik tanımlayıcılar hafif ama önemsiz rastgele bir çarpışma şansına sahip olacaklarsa, 40 bitlik bir tanımlayıcı neredeyse hiç olmaz.
supercat

3
@supercat: Hepsi doğru. Ben sadece böyle bir sabit sağlarsa, birinin de doğru bir değer verebileceğini
düşündüm

2
@ wchargin: Kişilerin kopyalar hakkında endişelenmeye başlaması gereken yerler açısından düşünmeyi tercih ederim. Eğer biri sqrt (N) 'nin çok altına düşerse, çarpışma olasılığı hızla düşer, rastgele üreteçte ciddi bir kusur olmadıkça, güvenli bir şekilde gerçekleşmeyeceklerini söylerler.
supercat

12

Bu sayıların yeterli bit olması durumunda, rastgele sayıların benzersiz olmasına güvenmenin yaygın olarak kabul edilebilir olduğu kabul edilir. Rasgele bir sayıyı tekrarlamanın tüm güvenliği bozacağı şifreleme protokolleri vardır. Ve kullanılan rasgele sayı üretecinde ciddi güvenlik açıkları olmadığı sürece, bu bir sorun olmamıştır.

UUID'lerin üretilmesi için kullanılan algoritmalardan biri etkili bir şekilde 122 rastgele bitten oluşan bir ID üretecek ve benzersiz olacağını varsayacaktır. Ve diğer algoritmaların ikisi, kabaca aynı çarpışma riskine sahip olan 122 bit'in benzersiz olduğu kesilen bir hash değerine dayanıyor.

Bu yüzden 122 bitin, rastgele bir ID'yi benzersiz hale getirmek için yeterli olmasına dayanan standartlar var, ancak 32 bit kesinlikle yeterli değil. 32 bitlik ID'lerde sadece bir çarpışma riski% 50'ye ulaşmadan önce yaklaşık 2¹⁶ ID alır çünkü 2¹⁶ ID'lerde her biri bir çarpışma olabilecek 2³¹ çifte yakın olacaktır.

122 bit bile, herhangi bir yeni tasarımda önerebileceğimden daha az. Bazı standardizasyonu takip etmek sizin için önemliyse, UUID kullanın. Aksi takdirde, 122 bitten daha büyük bir şey kullanın.

160 bitlik bir çıktıya sahip olan SHA1 hash fonksiyonu, kısmen güvenli olduğu düşünülmemektedir, çünkü 160 bit, çıktıların benzersizliğini garanti etmek için yeterli değildir. Modern karma fonksiyonlar 224 - 512 bit çıkışa sahiptir. Rasgele oluşturulmuş ID'ler, iyi bir güvenlik marjı ile benzersizliği sağlamak için aynı boyutları hedeflemelidir.


12
SHA-1 güvensiz olarak kabul edilir , çünkü rastgele çarpışma ihtimalinin yüksek olması nedeniyle çarpışmayı kaba kuvvetten daha hızlı bulabilen algoritmanın kendisine karşı özel saldırılar (yani rastgele olmayan) vardır. Kaba bir tahmin 122 saniyede bir bit ve saniyede 1 milyar (10 ^ 9) kimlik oranıyla,% 50 çarpışma şansına ulaşmadan önce 73 yıl alacağını söylüyor .
Saat

sqrt(2^122)= 2.3 katrilyon katrilyon
UUID'ler

2
@ 8bittree Bitcoin ağı her 10 dakikada bir 2⁷⁰ SHA2 karmasını hesaplar. Bu SHA1 karmaları olsaydı, bir çarpışma üretmek için sadece bir hafta sürerdi. UUID'ler aynı hızda üretilirse, bitcoin hash'leri hesaplar, bir çarpışma oluşturmak 2 saniyeden az sürer.
kasperd

Bitcoin tamamen çarpışma bulmaya çalışıyor ve son derece popüler ve hash bulmak için özel olarak tasarlanmış bir donanıma sahip. Şimdi, eğer OP, çılgınca popüler bir şifreleme para birimi ya da benzer bir şey yaratmayı planlıyorsa, kimlik başına yüzlerce ya da binlerce bit gerekebilir. Ancak, standartların UUID kütüphanesi yeterliyse, şartların bu şartlar altında olması gerekenden çok daha fazla çalışmayı teşvik edebileceğini varsayalım.
Saat 8'de

@ 8bittree Standart kitaplıkları kullanmak herhangi bir avantajsa, UUID için de geçerli. Ancak bazı rasgele baytları çıkarmak, urandomUUID kitaplığı kullanmaktan daha fazla iş değildir. Karşılaştırma için Python'da her ikisini de uyguladım ve her yöntem tam 25 karakter kaynak koduydu.
kasperd

3

Ben buna kötü uygulama derdim. Rastgele sayı basitçe benzersiz sayılar yaratmaz, sadece rastgele sayılar yaratır. Rasgele bir dağılımın bazı kopyaları içermesi muhtemeldir. Bir zaman dilimini ekleyerek bu durumu kabul edilebilir bir şekilde olası hale getirebilirsiniz. Geçerli saati sistem saatinden milisaniye cinsinden alırsanız. Bunun gibi bir şey:

parseToInt(toString(System.currentTimeMillis()) + toString(Random.makeInt()))

Uzun bir yol gidiyor. Açıkçası benzersizliği gerçekten garanti etmek için UUID / GUID kullanmanız gerekir. Ancak bunların üretilmesi pahalı olabilir, ancak üst üste binme olasılığının rastgele üretime aynı milisaniyede bir kopyası olması durumunda yukarıdakiler yeterli olacaktır.


9
Bazı sistemlerde 1ms uzun sürebilir.
quant_dev

7
Bu aslında çarpışma şansını azaltmaz. N sayısından sonra bir çarpışma olasılığı OP'nin orijinal çözümüyle tamamen aynıdır. Geçerli saati tohum olarak kullanmanın püf noktası genellikle tuşları sırayla atarken kullanılır.
Cort Ammon

2
@Fresheyeball Random.makeInt () aslında tamsayının minimum değerinden tamsayının maksimum değerine kadar düzgün bir dağılım oluşturmadığı sürece etkisinin olmadığından eminim. Bu işlev tarafından üretilen her geçmiş değer için, makeInt öğesinden rastgele bir değer vardır; bu kesin zaman adımı için bu değeri üreten, bir çarpışma oluşturur. MakeInt öğesindeki tüm değerler çiftlenebilir olduğu için, bir çarpışma olasılığı, zaman eklemeden bir çarpışma olasılığına tam olarak eşittir.
Cort Ammon

2
@CortAmmon bu, şimdiki zamanı bir tohum olarak kullanmaz ve bu N numaralarının tümü aynı milisaniyede üretilmediği sürece kesinlikle fark yaratır, çünkü farklı zaman damgası parçalarına sahip iki sayı hiçbir zaman çarpışmaz. Diğer yanıtlayıcının saniyede bir paket örneğini bir günde daha az% 50 çarpışma şansına sahip olduğunu hayal ederseniz, bunun bir saniyede bir pakette% 0'lık çarpışma şansı vardır, en azından currentTimeMillisetrafı sarana kadar .
Ocaklar

3
@hobbs Tamsayı taşmasını unuttun. Şimdi kullanılan anahtar, biri içeren System.currentTimeMillisve biri içeren 2 tam sayı içeren bir yapıysa Random.makeInt(), bir çarpışma olasılığı büyük ölçüde azalır. Ancak, bu örnekteki kodun yaptığı değildir. Herhangi bir önceki zaman ve rastgele değer ve herhangi bir şimdiki zaman göz önüne alındığında , çarpışma olasılığı, ilk etapta çarpışan iki rastgele sayının olasılığı ile aynıdır.
Cort Ammon

3

Hem başarısızlık olasılığına hem de başarısızlığın sonuçlarına bağlıdır.

Donanım insanlarının, yanlış sonuç olasılığı düşük olan bir algoritmanın (100 yıldaki 1 başarısızlık gibi bir şey) kabul edilebilir olduğunu düşündüğü yazılım ve donanım adamları arasındaki bir tartışmayı hatırlıyorum ve yazılım çalışanları bunun bir anatema olduğunu düşündüler. Donanım uzmanlarının rutin olarak beklenen arıza oranlarını hesapladığı ve örneğin kozmik ışınların neden olduğu rahatsızlıklar nedeniyle her şeyin zaman zaman yanlış cevaplar vereceği fikrine çok alıştığı ortaya çıktı; Yazılım arkadaşlarının% 100 güvenilirlik beklediğini garip buldular.


1

Tabii ki, iki rastgele 32-bit tamsayının ardışık olma olasılığı oldukça düşüktür, ancak bu tamamen imkansız değildir. Uygun mühendislik kararı, çarpışmaların sonuçlarının ne olacağını, ürettiğiniz sayıların hacminin bir tahminini, özgünlüğün gerekli olduğu ömrü ve kötü niyetli bir kullanıcının çarpışmalara neden olmaya başladığında ne olacağını temel alır.


0

Rasgele sayıların benzersiz olacağını varsaymak kabul edilebilir, ancak dikkatli olmalısınız.

Senin rastgele sayılar eşit dağıtıldığı varsayarsak, bir çarpışma olasılığı kabaca (n 2 /2) / k burada n Oluşturduğunuz rasgele sayı sayısıdır ve k "rastgele" sayı alabilir olası değerleri sayısıdır.

Astronomik olarak muhtemel olmayan bir sayı koymuyorsunuz, bu yüzden bunu 1 2 / 30'da (kabaca bir milyarda) alalım . Ayrıca, iki tane 30 paket ürettiğinizi söyleyelim (eğer her paket bir kilobayt veriyi temsil ediyorsa, bu toplam veri terabaytı anlamına gelir, bu büyük ama düşünülemez şekilde değildir). Olası en az 2 89 değere sahip rastgele bir sayıya ihtiyacımız var .

Öncelikle rastgele sayılarınızın yeterince büyük olması gerekir. 32 bit rasgele bir sayı, en fazla 2 32 olası değere sahip olabilir. Yeterince yüksek olmayan yoğun bir sunucu için.

İkincisi, rastgele sayı üreticinizin yeterince büyük bir iç duruma sahip olması gerekir. Eğer rastgele sayı üreticiniz sadece 32-bit bir iç duruma sahipse, ondan ne kadar değer ürettiğiniz önemli değil, yine de sadece en fazla 2 32 değer elde edersiniz .

Üçüncüsü, rastgele sayı üreticisinin bağlantıda değil, bağlantılarda benzersiz olması gerekirse, rasgele sayı üreticinizin iyi bir şekilde ekilmesi gerekir. Bu, özellikle programınız sık sık yeniden başlatıldığında geçerlidir.

Genel olarak, programlama dillerindeki "normal" rasgele sayı üreteçleri bu kullanım için uygun değildir. Kriptografi kütüphanelerinin sağladığı rasgele sayı üreteçleri genellikle.


0

Yukarıdaki cevapların bir kısmına dahil edildiğinde, rasgele sayı üretecinin gerçekten de 'düz' olduğu varsayımıdır - iki sayının bir sonraki üretilme olasılığı aynıdır.

Bu, çoğu rasgele sayı üreticisi için muhtemelen doğru değildir. Çoğu, bir tohuma tekrar tekrar uygulanan bazı yüksek dereceli polinom kullanır.

Bununla birlikte, bu programa bağlı, genellikle UUID'lerle birlikte birçok sistem var. Örneğin, Second Life'daki her nesne ve varlık rasgele oluşturulan 128 bitlik bir UUID'ye sahip ve nadiren çarpışıyorlar.


0

Birçok insan zaten yüksek kalitede cevaplar verdi, ancak birkaç küçük nokta eklemek istiyorum: İlk olarak, @nomadictype'in doğum günü paradoksuyla ilgili noktası mükemmel .

Başka bir nokta: rastgelelik, insanların sıradan kabul edebileceği kadar üretip tanımlamak için kolay değildir. (Aslında, mevcut rastgelelik için istatistiksel testler vardır).

Bununla birlikte, insanların bağımsız olayların bir şekilde birbirlerini etkilediğini varsaydığı istatistiksel bir yanlışlık olan Kumarbaz Yanılgısının farkında olmak önemlidir . Rastgele olaylar genellikle birbirlerinden istatistiksel olarak bağımsızdır - yani rastgele bir "10" oluşturursanız, gelecekte en az "10" üretme olasılığınızı değiştirmez. (Belki birileri bu kuralın bir istisnasını bulabilirdi, ama bunun hemen hemen tüm rasgele sayı üreteçleri için geçerli olacağını beklerdim).

Cevabım Yani eğer olmasıdır olabilir rasgele sayı yeterince uzun dizi benzersiz olduğunu varsayalım dair net bir istatistiksel model olacağından, gerçekten rasgele sayılar olmaz. Ayrıca, her yeni sayının bağımsız bir olay olmadığı anlamına gelir, çünkü örneğin 10 üretirseniz, gelecek 10'ları üretme olasılığının% 0 olacağı anlamına gelir (muhtemelen gerçekleşemez), artı bu, 10'dan farklı bir sayı alma olasılığını artıracağınız anlamına gelir (yani, ne kadar fazla sayı elde ederseniz, kalan sayıların her birinin olasılığı da o kadar artar).

Dikkate alınması gereken bir şey daha var: Powerball'u tek bir oyunda oynamayı kazanma şansı, anladığım kadarıyla, yaklaşık 175 milyonda 1. Ancak, birinin kazanma şansı bundan çok daha fazla. Sen oran daha çok ilgileniyorsanız birisi herhangi bir özel sayı / "kazanan" yinelendiği oran daha (yani yinelenen olmak) "kazanan".


Eğer biri 4096 bitlik tanımlayıcıları, her bir bitin aynı veya başka herhangi bir tanımlayıcıda oluşturulmuş herhangi bir başka bitten bağımsız olarak 0 veya 1 olması muhtemel olacak şekilde üretiyorsa, iki tanımlayıcının eşleşme olasılığı biri gözlemlenebilir evrendeki kabaca 4.0E81 atomlarının her biri için rastgele farklı bir tanımlayıcı oluştursa bile, ufukta küçük olun. Bu tür tanımlayıcıların neredeyse kesinlikle benzersiz olacağı gerçeği, hiçbir şekilde onları "rastgele olmayan"
yapmaz

@supercat Bu doğru - yeterince büyük bir sayı verildiğinde, yinelenenlerin oluşması muhtemel değildir, ancak imkansız değildir. Bu, benzersiz olmamanın sonuçlarının ne kadar kötü olduğuna ve OP'nin tanımladığı şeyin iyi bir fikir olup olmadığına gerçekten bağlı.
EJoshuaS - Monica,

Eğer rastlantısal bir şans çarpışma olasılığı, benzersiz bir kimliğe dayanan cihazları yok eden meteor çarpması ihtimalinden daha küçükse, mühendislik açısından bakıldığında, eskisi hakkında endişelenmenize gerek yoktur. Rastgele sayıların bağımsız olmamasına neden olabilecek herhangi bir şey için endişelenmeye ihtiyaç duyulur, ancak rastgele çarpışmalar sorun olmazdı.
supercat

@supercat Bunu yanlış okuduğunuzu düşünüyorum, doğum günü paradoksunun diğer cevabını görün, sanırım hesapladığınızdan çok daha büyük bir çarpışma - OP sadece 32-bit bir sayı kullanıyor, bu yüzden nerede olduğunuzdan emin değilim. 4096 alıyorsanız, ve göçebe türünün, bu uzunluktaki bir dizi ile nihai bir çarpışma olasılığını gösterdiği gibi, aslında şaşırtıcı derecede yüksek.
EJoshuaS - Monica,

Çarpışmalar kabul edilemezse, küçük popülasyonlar için bile 32 bit sayının çok kısa olduğu konusunda haklısın. Eğer biri yeterince büyük bir sayı kullanırsa, rasgele çarpışma olasılığını, kişinin Just Won't Happen'in güvenli bir şekilde olduğunu varsaydığı noktaya indirgeyebilir ve birçok durumda daha büyük bir sayı kullanmak, başka araçlar kullanmaya çalışmaktan daha iyi olabilir. benzersizliği sağlamak, ikincisi genellikle, bir sistemin saati sıfırlansa veya sistem bir yedekten yeniden yüklense bile geri alınamayan veya geri alınamayan durum geçişlerine erişimin olmasını gerektirir.
supercat

0

Kaç bit kullandığınız önemli değil - iki "rasgele" sayının farklı olacağını garanti edemezsiniz. Bunun yerine, IP adresi veya bilgisayarın diğer ağ adresi ve sıralı bir numara, tercihen bir HONKIN 'BÜYÜK sıralı sayı - 128 bit (açıkça imzasız) gibi iyi bir başlangıç ​​gibi sesler kullanmanızı öneririm, ancak 256 daha iyi olurdu.


-1

Hayır tabii değil. Örnekleri değiştirmeden kullanıyorsanız, çoğaltma olasılığı - ancak küçük - olabilir.

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.