Question

Je comprends les différences entre les deux des docs.

uuid1():
Générer un UUID à partir d'un identifiant d'hôte, le numéro de séquence, et l'heure courante

uuid4():
Générer un UUID aléatoire.

uuid1 utilise la machine d'info / séquence / temps pour générer un UUID. Quels sont les avantages et les inconvénients de l'utilisation de chacun?

Je sais que uuid1() peut avoir des problèmes de confidentialité, car il est basé sur des informations machine. Je me demande s'il y a plus subtil au moment de choisir l'un ou l'autre. Je viens d'utiliser uuid4() en ce moment, car il est un UUID complètement aléatoire. Mais je me demande si je devrais utiliser uuid1 pour réduire le risque de collisions.

En fait, je cherche les conseils des gens pour les meilleures pratiques sur l'utilisation de l'un par rapport à l'autre. Merci!

Était-ce utile?

La solution

uuid1() est garanti pour produire aucune collision (en supposant que vous ne créez pas un trop grand nombre d'entre eux en même temps). Je ne l'utiliser s'il est important qu'il n'y a aucun lien entre le uuid et l'ordinateur, comme l'adresse MAC se sert pour le rendre unique sur plusieurs ordinateurs.

Vous pouvez créer des doublons en créant plus de 2 14 uuid1 en moins de 100ns, mais ce n'est pas un problème pour la plupart des cas d'utilisation.

uuid4() génère, comme vous le dites, un UUID aléatoire. La chance d'une collision est vraiment, vraiment, vraiment petit. Assez petit, que vous ne devriez pas vous inquiéter à ce sujet. Le problème est qu'un mauvais générateur de nombres aléatoires rend plus susceptibles d'avoir des collisions.

Cette excellente réponse par Bob Aman résume bien. (Je recommande de lire toute la réponse.)

  

Franchement, dans un seul espace d'application   sans acteurs malveillants, la   l'extinction de toute vie sur terre   se produire longtemps avant d'avoir une   collision, même sur une version 4 UUID,   même si vous générez un assez grand nombre   UUIDs par seconde.

Autres conseils

Un exemple quand vous pouvez envisager uuid1() plutôt que uuid4() est lorsque UUID sont produits sur des machines séparées, par exemple lorsque plusieurs transactions en ligne sont processus sur plusieurs machines à des fins d'échelle.

Dans une telle situation, les risques d'avoir des collisions en raison de mauvais choix dans la façon dont les générateurs de nombres pseudo-aléatoires sont initialisés, par exemple, et aussi le nombre potentiellement plus élevés de UUID produits rendent plus susceptibles la possibilité de créer des ID en double .

Un autre intérêt de uuid1(), dans ce cas est que la machine sur laquelle a été initialement produite chaque GUID est implicitement enregistrée (dans la partie « noeud » de UUID). Ceci et les informations de temps, peut aider si seulement le débogage.

Mon équipe a juste couru en difficulté à utiliser UUID1 pour un script de mise à niveau de base de données où nous avons généré ~ 120k UUID dans quelques minutes. La collision UUID a conduit à la violation d'une contrainte de clé primaire.

Nous avons mis à jour 100s des serveurs, mais sur nos instances Amazon EC2 nous avons rencontré ce problème plusieurs fois. Je soupçonne une mauvaise résolution d'horloge et le passage à UUID4 résolu pour nous.

Une chose à noter lors de l'utilisation uuid1, si vous utilisez l'appel par défaut (sans donner paramètre clock_seq) vous avez une chance de courir dans les collisions: vous avez seulement 14 bits de hasard (générant 18 entrées dans 100ns vous donne environ 1% risques de collision voir anniversaire paradoxe / attaque). Le problème ne se produira jamais dans la plupart des cas d'utilisation, mais sur une machine virtuelle avec une faible résolution de l'horloge, il vous mordre.

Peut-être quelque chose qui est non mentionné est celui de la localité.

Une adresse MAC ou commande en fonction du temps (UUID1) peut se permettre des performances accrues de base de données, car il est moins de travail pour trier des nombres plus-ensemble que ceux distribués au hasard (UUID4) (voir ici ).

Une deuxième question connexe est que l'utilisation UUID1 peut être utile pour le débogage, même si les données d'origine est perdue ou non explicitement stockées (ce qui est évidemment en conflit avec la question de la vie privée mentionnée par l'OP).

En plus de la réponse acceptée, il y a une troisième option qui peut être utile dans certains cas:

v1 avec MAC aléatoire ( "v1mc")

Vous pouvez faire un hybride entre v1 et v4 en générant délibérément UUID v1 avec une adresse MAC de diffusion aléatoire (ce qui est permis par la spécification v1). Le v1 UUID résultant est fonction du temps (comme v1 régulière), mais n'a pas toutes les informations spécifiques hôte (comme v4). Il est aussi beaucoup plus proche de v4 en elle de collision résistance: v1mc = 60 bits de temps + 61 bits aléatoires = 121 bits uniques; v4 = 122 bits aléatoires.

La première place que je rencontrais c'était Postgres' uuid_generate_v1mc () fonction. Je l'ai depuis utilisé l'équivalent python suivant:

from os import urandom
from uuid import uuid1
_int_from_bytes = int.from_bytes  # py3 only

def uuid1mc():
    # NOTE: The constant here is required by the UUIDv1 spec...
    return uuid1(_int_from_bytes(urandom(6), "big") | 0x010000000000)

(note: J'ai une plus + version plus rapide qui crée l'objet UUID directement, peut envoyer des messages si quelqu'un veut)


En cas de gros volumes d'appels / seconde, ce qui a le potentiel pour le système d'échappement aléatoire. Vous peut au lieu d'utiliser le module random stdlib (il sera probablement aussi plus rapide). Mais attention: il ne faut que quelques centaines de UUID devant un attaquant peut déterminer l'état RNG, et donc prédire partiellement UUID futures.

import random
from uuid import uuid1

def uuid1mc_insecure():
    return uuid1(random.getrandbits(48) | 0x010000000000)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top