Quelle version d'UUID utiliser?

332

Quelle version de l'UUID devez-vous utiliser? J'ai vu beaucoup de discussions expliquant ce que chaque version implique, mais j'ai du mal à déterminer ce qui convient le mieux à quelles applications.

user1802143
la source
2
Quels sont vos choix?
Gabe
Tout ce qui fonctionne avec python. Je suppose donc que ce docs.python.org/2/library/uuid.html . 1,3,4,5.
user1802143
Si vous êtes curieux de connaître les versions 3 et 5, consultez cette question, Génération de l'UUID v5. Qu'est-ce que le nom et l'espace de noms? .
Basil Bourque

Réponses:

414

Il existe deux façons différentes de générer un UUID.

Si vous avez juste besoin d'un ID unique, vous voulez une version 1 ou une version 4.

  • Version 1: cela génère un identifiant unique basé sur une adresse MAC de carte réseau et une minuterie. Ces identifiants sont faciles à prévoir (étant donné un, je pourrais en deviner un autre) et peuvent être retracés sur votre carte réseau. Il n'est pas recommandé de les créer.

  • Version 4: celles-ci sont générées à partir de nombres aléatoires (ou pseudo-aléatoires). Si vous avez juste besoin de générer un UUID, c'est probablement ce que vous voulez.

Si vous devez toujours générer le même UUID à partir d'un nom donné, vous voulez une version 3 ou 5.

  • Version 3: cela génère un ID unique à partir d'un hachage MD5 d'un espace de noms et d'un nom. Si vous avez besoin d'une compatibilité descendante (avec un autre système qui génère des UUID à partir de noms), utilisez-le.

  • Version 5: cela génère un ID unique à partir d'un hachage SHA-1 d'un espace de nom et d'un nom. Ceci est la version préférée.

Gabe
la source
17
J'ajouterais: Si vous devez générer un reproducibleUUID à partir d'un nom donné, vous voulez une version 3 ou 5. Si vous alimentez cet algorithme avec la même entrée, il générera la même sortie.
anregen
3
Dans un environnement de cloud computing (comme AWS ou GAE), il semblerait que la faiblesse de la version 1 soit atténuée dans l'oubli. Où il est probable que des milliers d'adresses MAC différentes soient appliquées au générateur UUID d'une application donnée au fil du temps, éliminant la prévisibilité et / ou la traçabilité.
Buffalo Rabor
3
@ user239558 Étant donné que l'objectif d'un UUID est son caractère unique, UUIDv5 peut toujours être préféré.
Épicuriste du
7
Ce commentaire sur la version 1 étant "non recommandé", est trop simpliste. Dans de nombreuses situations, celles-ci sont en effet fines et préférables. Mais si vous avez des problèmes de sécurité concernant la fuite de l'un ou l'autre de ces éléments d'information d'un UUID qui pourraient être mis à la disposition d'acteurs non fiables: (a) l'adresse MAC de la machine créant l'UUID, ou (b) la date et l'heure de création, puis évitez la version 1. Si ces deux informations ne sont pas sensibles, la version 1 est un excellent moyen de procéder.
Basil Bourque
9
Qu'est-il arrivé à la version 2?
Matthew Woo
53

Si vous voulez un nombre aléatoire, utilisez une bibliothèque de nombres aléatoires. Si vous voulez un identifiant unique avec effectivement 0,00 ... beaucoup plus de 0 ici ... 001% de chances de collision, vous devez utiliser UUIDv1. Voir le post de Nick pour UUIDv3 et v5.

UUIDv1 n'est PAS sécurisé. Ce n'est pas censé l'être. Il est censé être UNIQUE, pas indiscutable. UUIDv1 utilise l'horodatage actuel, plus un identifiant de machine, ainsi que des éléments aléatoires pour créer un nombre qui ne sera plus jamais généré par cet algorithme. Cela est approprié pour un ID de transaction (même si tout le monde fait des millions de transactions / s).

Pour être honnête, je ne comprends pas pourquoi UUIDv4 existe ... à la lecture de la RFC4122 , il semble que cette version n'élimine PAS la possibilité de collisions. C'est juste un générateur de nombres aléatoires. Si cela est vrai, alors vous avez une très BONNE chance que deux machines dans le monde finissent par créer le même "UUID" v4 (cite parce qu'il n'y a pas de mécanisme pour garantir U.niversal U.niqueness). Dans cette situation, je ne pense pas que l'algorithme appartient à un RFC décrivant des méthodes pour générer des valeurs uniques. Il appartiendrait dans un RFC de générer un caractère aléatoire. Pour un ensemble de nombres aléatoires:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)
anregen
la source
67
Vous ne verrez pas deux implémentations d'UUID version 4 entrer en collision, sauf si vous générez un milliard d'UUID chaque seconde pendant un siècle et gagnez un tirage au sort . Rappelez-vous, set_sizeest 2 ^ 122, ce qui est très grand .
Kevin
8
L'algorithme V4 n'est pas série, ce qui signifie qu'il y a une chance que les deux premiers UUID générés par v4 puissent correspondre. Le fait qu'il existe de nombreuses options ne signifie pas que vous devez manquer d'options uniques avant de générer une répétition. Cela pourrait arriver à tout moment.
anregen
7
Vous ne faites pas vraiment le calcul. Nous (en tant qu'espèce) ne générons pas 1 milliard d'UUID par seconde. Nous avons donc plus de 100 ans avant la première collision (en moyenne).
Kevin
31
La V4 "pourrait" entrer en collision, mais la probabilité est exceptionnellement faible que pour la plupart des cas d'utilisation, elle en vaut le risque. Re: "deux machines dans le monde finissent par créer le même 'UUID'v4", bien sûr, mais ce n'est pas un problème car la plupart des machines dans le monde qui utilisent les UUID les utilisent dans des contextes différents. Je veux dire, si je génère le même UUID pour ma propre application interne que pour votre application interne, alors cela n'a pas d'importance. Les collisions n'ont d'importance que si elles se produisent dans le même contexte. (rappelez-vous, même au sein d'une application, de nombreux UUID ne doivent pas être uniques dans l'ensemble de l'application, juste le contexte dans lequel ils sont utilisés)
6
Il semble donc que si vous n'avez pas besoin que votre Guid soit sécurisé, utilisez la version 1. Si vous en avez besoin et que vous vous sentez chanceux (ou vraiment, ne vous sentez pas malchanceux), utilisez la version 4.
Vaccano
16

C'est une question très générale. Une réponse est: "cela dépend du type d'UUID que vous souhaitez générer". Mais un meilleur est celui-ci: "Eh bien, avant de répondre, pouvez-vous nous expliquer pourquoi vous devez coder votre propre algorithme de génération d'UUID au lieu d'appeler la fonctionnalité de génération d'UUID fournie par la plupart des systèmes d'exploitation modernes?"

Faire cela est plus facile et plus sûr, et puisque vous n'avez probablement pas besoin de générer le vôtre, pourquoi vous embêter à coder une implémentation? Dans ce cas, la réponse devient l'utilisation quel que soit votre O / S, votre langage de programmation ou votre framework. Par exemple, sous Windows, il existe CoCreateGuid ou UuidCreate ou l'un des divers wrappers disponibles à partir des nombreux frameworks utilisés. Sous Linux, il y a uuid_generate .

Si, pour une raison quelconque, vous avez absolument besoin de générer le vôtre, alors ayez au moins le bon sens de ne pas générer des UUID v1 et v2. Il est difficile de les corriger. Restez-en plutôt aux UUID v3, v4 ou v5.

Mise à jour : Dans un commentaire, vous mentionnez que vous utilisez Python et un lien vers celui-ci . En regardant à travers l'interface fournie, l' option la plus simple pour vous serait de générer un UUID v4 (c'est-à-dire créé à partir de données aléatoires) en appelant uuid.uuid4().

Si vous avez (ou pouvez) hacher des données à partir desquelles générer un UUID, vous pouvez utiliser la v3 (qui repose sur MD5) ou la v5 (qui repose sur SHA1). La génération d'un UUID v3 ou v5 est simple: choisissez d'abord le type d'UUID que vous souhaitez générer (vous devriez probablement choisir v5), puis choisissez l'espace de noms approprié et appelez la fonction avec les données que vous souhaitez utiliser pour générer l'UUID à partir de. Par exemple, si vous hachez une URL, vous utiliserez NAMESPACE_URL:

uuid.uuid3(uuid.NAMESPACE_URL, 'https://ripple.com')

Veuillez noter que cet UUID sera différent de l'UUID v5 pour la même URL, qui est généré comme ceci:

uuid.uuid5(uuid.NAMESPACE_URL, 'https://ripple.com')

Une bonne propriété des URL v3 et v5 est qu'elles devraient être interopérables entre les implémentations. En d'autres termes, si deux systèmes différents utilisent une implémentation conforme à la RFC4122, ils (ou du moins devraient ) générer tous les deux le même UUID si toutes les autres choses sont égales (c'est-à-dire générer la même version UUID, avec le même espace de noms et le même mêmes données). Cette propriété peut être très utile dans certaines situations (en particulier dans les scénarios de stockage adressable au contenu), mais peut-être pas dans votre cas particulier.

Nik Bougalis
la source
4
Je suppose que c'est parce que OP n'a pas demandé: comment "coder [mon] propre algorithme de génération d'UUID au lieu d'appeler la fonctionnalité de génération d'UUID fournie par la plupart des systèmes d'exploitation modernes?"
anregen
Mis à part cela, je pense que c'est une bonne explication de UUIDv3 et v5. Voir ma réponse ci-dessous pour savoir pourquoi je pense que la v1 peut être un bon choix.
anregen
qu'est-ce que NAMESPACE_URL? c'est une variable que je peux obtenir? d'où?
stackdave
@stackdave NAMESPACE_URLest un UUID généralement égal à 6ba7b811-9dad-11d1-80b4-00c04fd430c8, suivant la recommandation faite à la page 30 de la RFC-4122 .
Jamie Ridding
2

La documentation Postgres décrit les différences entre l' UUIDart. Quelques-uns:

V3:

uuid_generate_v3(namespace uuid, name text) - Cette fonction génère un UUID version 3 dans l'espace de noms donné en utilisant le nom d'entrée spécifié.

V4:

uuid_generate_v4 - Cette fonction génère un UUID version 4, qui est entièrement dérivé de nombres aléatoires.

Eugen Konkov
la source