web-dev-qa-db-fra.com

GUID collisions possibles?

Je travaille sur une base de données dans SQL Server 2000 qui utilise un GUID pour chaque utilisateur qui utilise l'application à laquelle il est lié. D'une manière ou d'une autre, deux utilisateurs se sont retrouvés avec le même GUID. Je sais que Microsoft utilise un algorithme pour générer un GUID aléatoire qui a un risque extrêmement faible de provoquer des collisions, mais une collision est-elle toujours possible?

111
Jason Baker

En gros, non. Je pense que quelqu'un est allé fouiner avec votre base de données. Selon la version GUID que vous utilisez, la valeur est soit unique (pour des éléments tels que les GUID de la version 1), soit à la fois unique et imprévisible (pour des éléments tels que les GUID de la version 4). Implémentation de SQL Server pour leur fonction NEWID () semble utiliser un nombre aléatoire de 128 bits, donc vous n'allez pas avoir de collision.

Pour une probabilité de collision de 1%, vous devez générer environ 2 600 000 000 000 000 000 0 GUID.

122
Tom Ritter

Fondamentalement, ils ne sont pas possibles!, les chances sont astronomiquement faibles.

Mais ... je suis la seule personne au monde que je connaisse, qui a eu une GUID colision une fois (yep!).

Et j'en suis sûr, et que ce n'était pas une erreur.

Comment cela s'est-il produit, dans une petite application qui s'exécutait sur Pocket PC, à la fin d'une opération une commande qui a généré un GUID doit être émise. La commande après avoir été exécutée sur le serveur, il a été stocké dans une table de commandes sur le serveur avec la date d'exécution. Un jour, lorsque je déboguais, j'ai émis la commande de module (avec le nouveau GUID attaché) et rien ne s'est produit. Je l'a fait à nouveau (avec le même guid, car le guid n'a été généré qu'une seule fois au début de l'opération), et encore, et rien, essayant enfin de savoir pourquoi la commande ne s'exécute pas, j'ai vérifié la table de commandes, et la même GUID car la version actuelle a été insérée il y a 3 semaines. Je n'y croyais pas, j'ai restauré une base de données à partir d'une sauvegarde de 2 semaines et le guid était là. J'ai vérifié le code, le nouveau guid était fraîchement La collision Pow guid, ne s'est produite qu'une seule fois, mais j'aurais vraiment aimé gagner au loto à la place, la chance est plus grande :).

Modifier: il y a certains facteurs qui auraient pu augmenter considérablement les chances que cela se produise, l'application s'exécutait sur l'émulateur PocketPC et l'émulateur a une fonction d'enregistrement de l'état, ce qui signifie que chaque fois que l'état est restauré, l'heure locale est également restaurée. et le guid est basé sur le temporisateur interne .... aussi l'algorithme de génération de guid pour le cadre compact pourrait être moins complet que par exemple celui COM ...

103
Pop Catalin

Ils sont théoriquement possibles, mais avec des nombres possibles de 3,4E38, si vous créez des dizaines de billions de GUID en un an, la chance d'en avoir un doublon est de 0,0000000000006 ( Source ).

Si deux utilisateurs se retrouvaient avec le même GUID, je parierais qu'il y a un bogue dans le programme qui provoque la copie ou le partage des données.

29
Ben Hoffstein

Voyons d'abord les risques de collision de deux GUID. Ce n'est pas, comme d'autres réponses l'ont indiqué, 1 sur 2 ^ 128 (10 ^ 38) à cause du paradoxe d'anniversaire , ce qui signifie que pour une probabilité de 50% de collision de deux GUID, la probabilité est en fait de 1 dans 2 ^ 64 (10 ^ 19) qui est beaucoup plus petit. Cependant, il s'agit toujours d'un très grand nombre, et en tant que tel, la probabilité de collision en supposant que vous utilisez un nombre raisonnable de GUID est faible.

Notez également que les GUID ne contiennent ni horodatage ni adresse MAC, comme beaucoup de gens semblent également le croire. Cela était vrai pour les GUID v1 mais maintenant les GUID v4 sont utilisés, qui sont simplement un nombre pseudo-aléatoire ce qui signifie que la possibilité de collision est sans doute plus élevée car ils ne sont plus uniques à une époque et à une machine.

Donc, essentiellement, la réponse est oui, les collisions sont possibles. Mais ils sont hautement improbables.

Edit: fixe à dire 2 ^ 64

20
Greg Beech

Les chances de collision de deux GUID aléatoires (~ 1 sur 10 ^ 38) sont inférieures à celles de ne pas détecter un paquet TCP/IP corrompu (~ 1 sur 10 ^ 10). http://wwwse.inf.tu-dresden.de/data/courses/SE1/SE1-2004-lec12.pdf , page 11. Cela vaut également pour les lecteurs de disque, les lecteurs de CD, etc. ...

Les GUID sont statistiquement uniques et les données que vous lisez à partir de la base de données ne sont statistiquement correctes.

17
Tony Lee

Je considérerais le rasoir d'Occam comme un bon guide dans ce cas. Il est incroyablement improbable que vous ayez une collision GUID. Il est beaucoup plus probable que vous ayez un bogue ou que quelqu'un dérange vos données.

12
Jason Jackson

Voir l'article de Wikipedia Global Identifiant Unique . Il existe plusieurs façons de générer des GUID. Apparemment, l'ancienne (?) Façon utilisait l'adresse Mac, un horodatage vers une unité très courte et un compteur unique (pour gérer les générations rapides sur le même ordinateur), donc les dupliquer est presque impossible. Mais ces GUID ont été supprimés car ils pouvaient être utilisés pour retrouver les utilisateurs ...

Je ne suis pas sûr du nouvel algorithme utilisé par Microsoft (l'article dit qu'une séquence de GUID peut être prédite, on dirait qu'ils n'utilisent plus d'horodatage? L'article Microsoft lié ci-dessus dit autre chose ...).

Maintenant, les GUID sont soigneusement conçus pour être, par leur nom, uniques au monde, donc je risquerai que ce soit impossible ou de très très très faible probabilité. Je chercherais ailleurs.

11
PhiLho

Deux machines Win95 qui ont des cartes Ethernet avec des adresses MAC en double émettront des GUIDS en double dans des conditions strictement contrôlées, surtout si, par exemple, l'alimentation est coupée dans le bâtiment et qu'elles démarrent toutes les deux en même temps.

9
Joshua

Je connais des gens comme la réponse réconfortante selon laquelle les GUID sont magiques et garantis d'être uniques, mais en réalité, la plupart des GUID ne sont que des nombres aléatoires de 121 bits (sept des bits sont gaspillés en formatage). Si vous ne vous sentez pas à l'aise avec un grand nombre aléatoire, vous ne devriez pas vous sentir à l'aise avec un GUID.

5
Rick Yorgason

Je préfère ceci avec "Je ne suis pas une personne en réseau, donc je peux faire des phrases complètement incohérentes après.".

Lorsque je travaillais à l'Illinois State University, nous avions deux ordinateurs de bureau Dell, commandés à des moments différents. Nous avons mis le premier sur le réseau, mais lorsque nous avons essayé de mettre le second sur le réseau, nous avons commencé à recevoir des erreurs folles. Après de nombreux dépannages, il a été déterminé que les deux machines produisaient les mêmes GUID (je ne sais pas exactement pourquoi, mais cela les rendait toutes les deux inutilisables sur le réseau). Dell a en fait remplacé les deux machines comme défectueux.

3
John Kraft

Le code utilisé pour générer un GUID pourrait-il contenir un bogue? Oui, bien sûr. Mais la réponse est la même que pour un bogue de compilation - votre propre code est des commandes de magnitude plus susceptibles d'être buggy, alors regardez d'abord.

3
Mark Ransom

Bien sûr, c'est possible ... Probable? Peu probable, mais c'est possible.

N'oubliez pas que la même machine génère chaque GUID (le serveur), donc une grande partie du "caractère aléatoire" basé sur des informations spécifiques à la machine est perdu.

2
FlySwat

Juste pour les sourires, essayez le script suivant ... (fonctionne sur SQL 2005, pas sûr de 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'exécution répétée de cette opération (prend moins d'une seconde) produit une plage assez large dès la première sélection, même avec un intervalle de temps extrêmement court. Jusqu'à présent, la deuxième sélection n'a rien produit.

1
GalacticCowboy

Impossible si les utilisateurs ont des machines différentes avec des cartes réseau, et même si ce n'est pas encore un risque presque théorique extrêmement marginal.

Personnellement, je chercherais ailleurs car il s'agit probablement d'un bug plutôt que d'un GUID clash ...

À condition bien sûr de ne pas couper les bits du GUID pour le raccourcir.

0
Richard Harrison

Bien sûr, c'est possible, et peut-être même probable. Ce n'est pas comme si chaque GUID est dans une partie aléatoire de l'espace numérique possible. Dans le cas où deux threads tentaient d'en générer un simultanément, sauf une sorte de fonction centralisée GUID avec un sémaphore autour, ils pourraient se retrouver avec la même valeur.

0
Kirk Strauser

Il est très peu probable que vous rencontriez des collisions GUID si vous les générez via quelque chose comme la fonction NEWID() dans SQL Server (bien que cela soit bien sûr possible, comme d'autres réponses) Une chose qu'ils n'ont pas soulignée est qu'il est en fait très probable que vous rencontrerez des collisions si vous générez des GUID en JavaScript sur des navigateurs dans la nature. Non seulement il y a parfois des problèmes dans le RNG dans différents navigateurs, mais j'ai également rencontré des problèmes où les araignées Google semblent mettre en cache les résultats de fonctions comme ça, et ont fini par transmettre à plusieurs reprises les mêmes GUID à nos systèmes.

Voir les différentes réponses ici pour plus de détails:

Collisions lors de la génération d'UUID en JavaScript?

0
Ken Smith