Sono possibili collisioni GUID?


128

Sto lavorando su un database in SQL Server 2000 che utilizza un GUID per ogni utente che utilizza l'app a cui è legato. In qualche modo, due utenti hanno finito con lo stesso GUID. So che microsoft utilizza un algoritmo per generare un GUID casuale che ha una probabilità estremamente bassa di causare collisioni, ma è ancora possibile una collisione?


11
Tutti dicono di no, ma ho già scontrato 1 UniqueIdentifier con un set di dati di meno di mezzo milione di record, MSSQL 2008 R2
Behrooz,

2
@Behrooz Yikes. Non è impossibile grazie al nostro amico paradosso del compleanno, ma è ancora follemente sfortunato con GUID v4 completamente casuali. Forse stavi usando una strategia di generazione GUID più debole?
Craig Ringer,

6
@Behrooz Wow. È una fortuna scioccante.
Craig Ringer,

6
@Behrooz questo è probabilmente un numero pseudo casuale difettoso usato in MSSQL (non sarei sorpreso se hanno un seme a 32 bit nel loro generatore o simili data la qualità del loro software). La matematica non mente. Questa possibilità è così piccola che puoi essere il 99.9999999999 (e molto dopo il 9)% che il generatore guid MSSQL è difettoso (o può essere un generatore pseudo casuale che viene utilizzato per generare GUID) o hai fatto un errore.
Alex,

2
Adoro come in questo preciso momento, sia la domanda che la risposta selezionata abbiano 128 punti. Coincidenza? 🤔
Caio Cunha il

Risposte:


127

Fondamentalmente no. Penso che qualcuno sia andato in rovina con il tuo database. A seconda della versione GUID in uso, il valore è unico (per cose come GUID versione 1) o sia unico che imprevedibile (per cose come la versione 4 GUID). L'implementazione di SQL Server per la loro funzione NEWID () sembra utilizzare un numero casuale a 128 bit, quindi non si otterrà una collisione.

Per una probabilità dell'1% di collisione, è necessario generare circa 2.600.000.000.000.000.000 di GUID.


3
È quello che ho pensato, ma volevo solo assicurarmi di non poterlo escludere. Non si sa mai quali tipi di bug strani potrebbero apparire in un software di 8 anni. :)
Jason Baker,

6
In realtà non è più vero. Era vero per i GUID v1, ma non per quelli attuali v4. Vedi en.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm per maggiori informazioni.
Greg Beech,

97
Votazione negativa perché, in linea di principio (nella sua forma più grezza), sbagli dicendo "no" alla domanda "Sono possibili collisioni GUID?". È molto possibile. La probabilità che sia piccola, ma è possibile. Odio sembrare pedante, ma SO significa essere concisi e precisi.

13
inserisci "risolvere [1-exp [- (n ^ 2 / (2 * 2 ^ 128))]> 0,01, n]" in wolfram alpha per ottenere il risultato per l'1% ... Beaware che mentre questo numero sembra grande in contesto di UNA applicazione, certamente non è grande per il mondo intero. Se ogni computer sulla terra generasse GUID reali, causerebbero una collisione con probabilità dell'1% entro circa un secondo, supponendo che possano generare un GUID ogni nanosecondo (che è probabilmente abbastanza realistico in questi giorni). Pertanto, se si utilizzano GUID per gli ID del database, sono univoci. I GUID per ogni calcolo fatto sulla terra, si scontreranno immediatamente.
thesaint

11
Dire "No" non è possibile e quindi dire che esiste una probabilità dell'1% di ottenere una collisione quando viene generato un certo importo, sono conflitti diretti. La risposta corretta dovrebbe essere teoricamente - sì, una collisione potrebbe avvenire in modo casuale. Tuttavia, le probabilità di una collisione sono statisticamente minori di un asteroide che colpisce la Terra, rimbalzando sulla Terra e rimbalzando sulla Luna per colpire la Terra una seconda volta, nell'ora successiva.
Baaleos,

112

Fondamentalmente non sono possibili! , le probabilità sono astronomicamente basse .

Ma ... sono l'unica persona al mondo che conosco, che ha avuto una colisione GUID una volta (sì!).

E ne sono sicuro, e che non è stato un errore.

Come è potuto accadere, in una piccola applicazione in esecuzione su Pocket PC, al termine di un'operazione deve essere emesso un comando con un GUID generato. Il comando dopo che è stato eseguito sul server è stato archiviato in una tabella comandi sul server insieme alla data di esecuzione. Un giorno mentre stavo eseguendo il debug ho emesso il comando module (con il GUID appena generato allegato) e non è successo nulla. L'ho fatto di nuovo (con lo stesso guid, perché il guid è stato generato solo una volta all'inizio dell'operazione), e ancora, e niente, finalmente cercando di scoprire perché il comando non viene eseguito, ho controllato la tabella dei comandi, e lo stesso GUID di quello attuale è stato inserito 3 settimane fa. Non credendo a ciò, ho ripristinato un database dal backup di 2 settimane e il guid era lì. Controllato il codice, il nuovo guid è stato appena generato senza alcun dubbio.

Modifica: ci sono alcuni fattori che potrebbero aver aumentato notevolmente le possibilità che ciò accada, l'applicazione era in esecuzione sull'emulatore PocketPC e l'emulatore ha una funzione di salvataggio dello stato, il che significa che ogni volta che lo stato viene ripristinato viene ripristinata anche l'ora locale e il guid si basa sul timer interno .... anche l'algoritmo di generazione guid per il framework compatto potrebbe essere meno completo rispetto ad esempio a quello COM ...


38
Upvoted. Il salvataggio dello stato e la riproduzione genererebbero guide duplicate.
Joshua,

35
Probabilmente quello che è successo è stata un'implementazione GUID "cattiva". Il teorico probabilità erano molto basse, ma su Pocket PC ?? Chi può dire che non hanno preso una scorciatoia che ha portato quelle probabilità nella categoria "improbabile, ma possibile".
Dave Dopson,

9
Solo perché qualcosa ha una probabilità molto bassa di accadere non significa che non accadrà.
Renan,

3
Come ho detto sopra, le possibilità sono sempre più ridotte che è lecito ritenere che tu abbia commesso un errore o che MSSQL utilizzi un PRNG difettoso ( en.wikipedia.org/wiki/Pseudorandom_number_generator ). Ad esempio, è probabile che questo PRNG sia iniziato con un seme di piccole dimensioni. PRNG difettosi non sono rari (vedi schneier.com/paper-prngs.html ) - ad esempio un difetto è stato scoperto di recente in Android SDK - android-developers.blogspot.com/2013/08/… + usenix.org/conference/woot14 / programma-workshop / presentazione / ...
Alex

2
@Alex, l'errore era "Salva stato e ripristina" dall'emulatore, che ripristinava l'intera immagine dell'emulatore, incluso l'orologio dell'emulatore. Quindi dopo migliaia di operazioni di ripristino nell'arco di un anno, è stata generata una collisione guid. Hai ragione c'è stato un errore!
Pop Catalin,

34

Sono teoricamente possibili, ma con 3.4E38 possibili numeri, se si creano decine di trilioni di GUID in un anno, la possibilità di avere un duplicato è 0,00000000006 ( Fonte ).

Se due utenti finissero con lo stesso GUID, scommetterei che c'è un bug nel programma che sta causando la copia o la condivisione dei dati.


"ma con 3.4E38 numeri possibili" - no. Due GUID generati quasi contemporaneamente sullo stesso computer finirebbero con GUID estremamente simili.
Kirk Strauser,

4
Ciò dipenderebbe da come viene generato il GUID e alcune implementazioni basate sul tempo della CPU o sui millisecondi esagerano (si spera) qualunque calcolo basato sulla sua base di due GUID generati a distanza di millisecondi avrà una grande differenza.
Dalin Seivewright,

4
Con più di un processore su una macchina, se un guid è basato sul tempo e sull'indirizzo mac, ciascun core può emettere lo stesso guid nello stesso momento.
AndyM,

12
Sono abbastanza sicuro che qualsiasi implementazione GUID decente non lo farà
Guillaume86

1
@MatthewLock Il paradosso del compleanno è coperto dalla fonte. Controlla il link.
Zero3,

21

Innanzitutto vediamo la possibilità di una collisione di due GUID. Non è, come hanno affermato altre risposte, 1 su 2 ^ 128 (10 ^ 38) a causa del paradosso del compleanno , il che significa che per una probabilità del 50% di due GUID che si scontrano la probabilità è in realtà 1 su 2 ^ 64 (10 ^ 19) che è molto più piccolo. Tuttavia, questo è ancora un numero molto elevato e come tale la probabilità di collisione supponendo che si stia utilizzando un numero ragionevole di GUID è bassa.

Si noti inoltre che i GUID non contengono un timestamp o l'indirizzo MAC, come anche molte persone sembrano credere. Questo era vero per i GUID v1 ma ora vengono utilizzati i GUID v4, che sono semplicemente un numero pseudo-casuale, il che significa che la possibilità di collisione è probabilmente maggiore perché non sono più univoci per un tempo e una macchina.

Quindi essenzialmente la risposta è sì, le collisioni sono possibili. Ma sono altamente improbabili.

Modifica: risolto per dire 2 ^ 64


2
Mentre sono d'accordo con tutti i tuoi fatti, stai attento con la tua matematica. Dire che hai una possibilità 1 su 10 ^ 19 di far scontrare due GUID dipende dal numero di GUID presenti nel set. Per quella possibilità hai bisogno di ~ 2 ^ 32 GUID, quindi in quasi tutti gli scenari del mondo reale le probabilità sono molto più basse.
DocMax,

1
Hai un errore di battitura 1 in 10^64 (10^19), che penso dovrebbe essere 1 in 2^64 (10^19). Sono anche molto confuso su come pensi che il paradosso del compleanno si applichi a soli 2 numeri. Presumo che tu abbia guardato en.wikipedia.org/wiki/Birthday_paradox . La tabella mostra quante guide sono necessarie per una determinata probabilità di un duplicato. Da quella tabella una probabilità di 1 su 10 ^ 18 richiede 2.6 * 10 ^ 10 guide, non nulla di simile a due soli GUID.
Tony Lee,

Un punto: le guide v1 sono ancora ampiamente utilizzate e si basano sull'indirizzo MAC, in particolare nei database in quanto presentano caratteristiche desiderabili. Vedere UuidCreateSequential e di SQL Server involucro NEWSEQUENTIALID ( msdn.microsoft.com/en-us/library/windows/desktop/... ).
EBarr,

18

Le probabilità che due GUID casuali si scontrino (~ 1 su 10 ^ 38) sono inferiori alla possibilità di non rilevare un pacchetto TCP / IP corrotto (~ 1 su 10 ^ 10). http://wwwse.inf.tu-dresden.de/data/courses/SE1/SE1-2004-lec12.pdf , pagina 11. Questo vale anche per unità disco, unità cd, ecc ...

I GUID sono statisticamente univoci e i dati letti dal database sono statisticamente corretti.


Sei sicuro di non poter armare la mia rete, quindi meno di 1 su 10 ^ 28 pacchetti sono corrotti?
Giosuè,

13

Considererei il rasoio di Occam una buona guida in questo caso. È incredibilmente improbabile che tu abbia una collisione GUID. È molto più probabile che tu abbia un bug, o qualcuno che scherzi con i tuoi dati.


1
In realtà in questa situazione il rasoio di Occam non è affatto una buona guida! Occam's Razor afferma che il caso con i presupposti minimi è molto probabilmente corretto. In questa situazione il caso della collisione GUID è in realtà molto più semplice, ma Occam's Razor non si applica a una situazione come questa in cui sappiamo già che uno dei casi è incredibilmente improbabile.
Lockstock

11

Vedi l' identificatore univoco globale di Wikipedia articolo di . Esistono diversi modi per generare GUID. Apparentemente il vecchio modo (?) Utilizzava l'indirizzo Mac, un timestamp fino a un'unità molto corta e un contatore univoco (per gestire generazioni veloci sullo stesso computer), quindi renderli duplicati è quasi impossibile. Ma questi GUID sono stati eliminati perché potevano essere utilizzati per rintracciare gli utenti ...

Non sono sicuro del nuovo algoritmo utilizzato da Microsoft (l'articolo dice che è possibile prevedere una sequenza di GUID, sembra che non utilizzino più il timestamp? L'articolo Microsoft sopra riportato dice qualcos'altro ...).

Ora, i GUID sono accuratamente progettati per essere, per nome, unici a livello globale, quindi rischierò che sia impossibile o con probabilità molto molto molto basse. Vorrei cercare altrove.





9

Due macchine Win95 che dispongono di schede Ethernet con indirizzi MAC duplicati emetteranno GUID duplicati in condizioni strettamente controllate, soprattutto se, ad esempio, l'alimentazione si interrompe nell'edificio e si avviano entrambi contemporaneamente.


È comune che due macchine diverse abbiano lo stesso indirizzo MAC Ethernet?
Dave Lucre,

@DaveLucre: No, ma sono stati registrati degli incidenti.
Giosuè,

Sono davvero curioso di come questo avvenga. È più probabile con le macchine virtuali che generano casualmente un MAC per ogni scheda di rete? Non ho mai sentito parlare di NIC fisiche prodotte con MAC duplicati! Un po 'getta una chiave enorme nelle opere se ciò è possibile!
Dave Lucre,

Wow! Grazie per il link @Joshua! Che colossale rovina!
Dave Lucre,

@DaveLucre Ho usato alcune schede NIC USB molto economiche in cui TUTTI sono prodotti con lo stesso MAC. Ma ovviamente, ciò non ha nulla a che fare con la matematica della casualità e tutto con la pigrizia del produttore.
Rudolfbyker,

5

Premetto questo con "Non sono una persona in rete, quindi potrei fare frasi completamente incoerenti dopo".

Quando lavoravo all'Illinois State University, avevamo due desktop Dell, ordinati in momenti diversi. Abbiamo messo il primo sulla rete, ma quando abbiamo provato a mettere il secondo sulla rete abbiamo iniziato a ricevere errori folli. Dopo una lunga risoluzione dei problemi, è stato stabilito che entrambe le macchine stavano producendo lo stesso GUID (non sono sicuro del perché, ma le ha rese entrambe inutilizzabili sulla rete). Dell ha effettivamente sostituito entrambe le macchine come difettose.


3
Era specificamente il GUID. Ha qualcosa a che fare con il GUID generato dalle macchine quando si sono uniti alla rete. Dell ha impiegato diverse settimane per sostituire le macchine perché ritenevano impossibile che i GUID fossero gli stessi. Siamo stati in grado di riprodurre il problema, Dell ha ripreso le macchine e siamo riusciti a produrre gli stessi risultati sulle loro reti. Hanno finito per sostituire entrambe le macchine. Come ho detto, non sono una persona in rete, ma ricordo specificamente che si trattava di un problema con i GUID.
John Kraft,

5

Conosco persone come la risposta positiva che i GUID sono magici e garantiti come unici, ma in realtà la maggior parte dei GUID sono solo numeri casuali a 121 bit (sette dei bit sono sprecati nella formattazione). Se non ti senti a tuo agio con un grande numero casuale, non dovresti sentirti a tuo agio con un GUID.


11
Consiglia anche di non utilizzare le reti. O i computer. I bit di parità possono fare solo così tanto!
Rushyo,

Hai frainteso. Ci sono due cose che stavo cercando di dire in questo post: 1) Se hai bisogno di un grande numero casuale, usa un grande numero casuale. L'uso di un GUID come un grande numero casuale è inutilmente fuorviante. (2)
Rick Yorgason,

4
Di cui sono pienamente consapevole. Hai dichiarato "se non ti sentissi a tuo agio con un grande numero casuale". ma i GUID sono così unici che potresti scoprire che praticamente tutto il resto in un computer è più casuale, anche le operazioni che dai per scontate. Ci sono più possibilità che un anomalo errore di memoria rompa la colonna della tua identità rispetto a una (vera) collisione GUID. Non dovresti sentirti "a disagio" con loro. Se non sono ideali per lo scenario, va bene, ma non hanno bisogno di particolari precauzioni.
Rushyo,

3
Immagino che questo non vada da nessuna parte, ma ciò che la gente sta cercando di spiegarti è che i meccanismi di rilevamento errori in hardware comune come schede di rete o dischi rigidi utilizzano algoritmi che hanno maggiori probabilità di non rilevare un errore rispetto a te di ottenere una collisione GUID, quindi se fai affidamento su questi, puoi anche fare affidamento sui GUID
Guillaume86

1
@Rick, dipende da quanto è grande il tuo numero. Sicuramente non con un int di 4 byte o un bigint di 8 byte. GUID = 16 byte, quindi avrai bisogno di un'implementazione personalizzata a 16 byte per ottenere le stesse 2 ^ 128 combinazioni possibili. Quindi, in generale, se si usano numeri casuali "normali" o bigint, la possibilità di collisioni con un GUID è inferiore (tralasciando le considerazioni di algo casuali per ciascuno).
Wim Hollebrandse,

3

Il codice utilizzato per generare un GUID potrebbe contenere un bug? Sì, certo che potrebbe. Ma la risposta è la stessa di un bug del compilatore: il tuo codice è che gli ordini di grandezza hanno maggiori probabilità di essere difettosi, quindi guarda prima lì.


2

Certo che è possibile .... Probabile? Non è probabile, ma è possibile.

Ricorda, la stessa macchina sta generando ogni GUID (il server), quindi si perde gran parte della "casualità" basata su informazioni specifiche della macchina.


1

Solo per grins, prova il seguente script ... (funziona su SQL 2005, non sono sicuro circa 2000)

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

L'esecuzione ripetuta (richiede meno di un secondo) produce un intervallo abbastanza ampio dalla prima selezione, anche con un intervallo di tempo ESTREMAMENTE breve. Finora la seconda selezione non ha prodotto nulla.


1
Hai bisogno di altri 15 zeri alla fine del contatore per avere una probabilità del 50% di un duplicato. Ma, per l'amor di Dio, non farlo!
Jim Birchall,

0

Impossibile se gli utenti hanno macchine diverse con schede di rete, e anche se non è ancora un rischio quasi teorico estremamente marginale.

Personalmente guarderei altrove poiché è più probabile un bug piuttosto che uno scontro GUID ...

Ovviamente, non tagliare i bit dal GUID per renderlo più breve.


I GUID verrebbero generati sul server, quindi le schede di rete dell'utente non entrerebbero in gioco.
Tom Ritter,

0

Certo, è possibile, e forse anche probabile. Non è come se ogni GUID fosse in una porzione casuale del possibile spazio numerico. Nel caso in cui due thread abbiano tentato di generarne uno contemporaneamente, escludendo una sorta di funzione GUID centralizzata con un semaforo attorno, potrebbero finire con lo stesso valore.


0

È altamente improbabile che ti imbatterai in collisioni GUID se le stai generando attraverso qualcosa di simile al NEWID() funzione in SQL Server (anche se ovviamente possibile, come hanno sottolineato altre risposte). Una cosa che non hanno sottolineato è che in realtà è molto probabile che ti imbatterai in collisioni se stai generando GUID in JavaScript su browser in natura. A volte non solo ci sono problemi nell'RNG in diversi browser, ma ho anche incontrato problemi in cui gli spider di Google sembrano memorizzare nella cache i risultati di funzioni del genere e sono finiti ripetutamente passando lo stesso GUID ai nostri sistemi.

Vedi le varie risposte qui per maggiori dettagli:

Collisioni durante la generazione di UUID in JavaScript?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.