¿Qué versión de UUID usar?

332

¿Qué versión del UUID deberías usar? Vi muchos hilos explicando lo que implica cada versión, pero tengo problemas para descubrir qué es lo mejor para qué aplicaciones.

usuario1802143
fuente
2
¿Cuáles son tus elecciones?
Gabe
Cualquier cosa que funcione con python. Así que supongo que esto docs.python.org/2/library/uuid.html . 1,3,4,5.
user1802143
Si tiene curiosidad sobre las versiones 3 y 5, consulte esta pregunta, Generando v5 UUID. ¿Qué es el nombre y el espacio de nombres? .
Basil Bourque

Respuestas:

414

Hay dos formas diferentes de generar un UUID.

Si solo necesita una identificación única, quiere una versión 1 o 4.

  • Versión 1: Esto genera una identificación única basada en una dirección MAC de la tarjeta de red y un temporizador. Estos ID son fáciles de predecir (dado uno, podría adivinar otro) y pueden rastrearse hasta su tarjeta de red. No se recomienda crear estos.

  • Versión 4: se generan a partir de números aleatorios (o pseudoaleatorios). Si solo necesita generar un UUID, esto es probablemente lo que desea.

Si necesita generar siempre el mismo UUID a partir de un nombre de pila, desea una versión 3 o 5.

  • Versión 3: Esto genera una identificación única a partir de un hash MD5 de un espacio de nombres y nombre. Si necesita compatibilidad con versiones anteriores (con otro sistema que genera UUID a partir de nombres), use esto.

  • Versión 5: Esto genera una identificación única a partir de un hash SHA-1 de un espacio de nombres y nombre. Esta es la versión preferida.

Gabe
fuente
17
Agregaría: si necesita generar un reproducibleUUID a partir de un nombre dado, desea una versión 3 o versión 5. Si alimenta ese algoritmo con la misma entrada, generará la misma salida.
anregen
3
En un entorno de computación en la nube (como AWS o GAE), parece que la debilidad de la Versión 1 se mitiga en el olvido. Donde es probable que haya miles de direcciones MAC diferentes aplicadas al generador de UUID de una aplicación determinada a lo largo del tiempo, eliminando la previsibilidad y / o la trazabilidad.
Buffalo Rabor el
3
@ user239558 Dado que el objetivo de un UUID es su singularidad, aún se puede preferir UUIDv5.
Epicurista el
77
Ese comentario sobre la versión 1 "no recomendada" es demasiado simplista. En muchas situaciones, estos son realmente buenos y preferibles. Pero si tiene inquietudes de seguridad sobre la filtración de cualquiera de estos elementos de información de un UUID que podría estar disponible para actores no confiables: (a) la dirección MAC de la máquina que crea el UUID, o (b) la fecha y hora cuando se creó, luego evite la Versión 1. Si esas dos piezas de información no son sensibles, entonces la Versión 1 es una excelente manera de hacerlo.
Basil Bourque
99
¿Qué pasó con la versión 2?
Matthew Woo
53

Si desea un número aleatorio, use una biblioteca de números aleatorios. Si desea un identificador único con efectivamente 0.00 ... muchos más ceros aquí ... 001% de probabilidad de colisión, debe usar UUIDv1. Vea la publicación de Nick para UUIDv3 y v5.

UUIDv1 NO es seguro. No está destinado a ser. Está destinado a ser ÚNICO, no indescifrable. UUIDv1 usa la marca de tiempo actual, más un identificador de máquina, más algunas cosas aleatorias para crear un número que ese algoritmo nunca volverá a generar. Esto es apropiado para una ID de transacción (incluso si todos están haciendo millones de transacciones / s).

Para ser honesto, no entiendo por qué existe UUIDv4 ... al leer RFC4122 , parece que esa versión NO elimina la posibilidad de colisiones. Es solo un generador de números aleatorios. Si eso es cierto, tiene una muy buena posibilidad de que dos máquinas en el mundo eventualmente creen el mismo "UUID" v4 (cita porque no hay un mecanismo para garantizar la unicidad U. universal). En esa situación, no creo que el algoritmo pertenezca a un RFC que describa métodos para generar valores únicos. Pertenecería a un RFC sobre la generación de aleatoriedad. Para un conjunto de números aleatorios:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)
anregen
fuente
67
No verá colisionar dos implementaciones de UUID versión 4, a menos que genere mil millones de UUID por segundo durante un siglo y gane un lanzamiento de moneda . Recuerde, set_sizees 2 ^ 122, que es muy grande .
Kevin
8
El algoritmo V4 no es serial, lo que significa que existe la posibilidad de que los dos primeros UUID generados por v4 puedan coincidir. El hecho de que haya muchas opciones no significa que tenga que quedarse sin opciones únicas antes de generar una repetición. Eso podría suceder en cualquier momento.
anregen
77
Estás fallando en hacer los cálculos. Nosotros (como especie) no estamos generando mil millones de UUID por segundo. Así que tenemos más de 100 años hasta la primera colisión (en promedio).
Kevin
31
V4 "podría" colisionar, pero la probabilidad es excepcionalmente baja de que para la mayoría de los casos de uso valga la pena el riesgo. Re: "dos máquinas en el mundo eventualmente crean el mismo 'UUID'v4", bueno, claro, pero esto no es un problema porque la mayoría de las máquinas en el mundo que usan UUID las usan en diferentes contextos. Quiero decir, si genero el mismo UUID para mi propia aplicación interna que tú para tu aplicación interna, entonces no importa. Las colisiones solo importan si ocurren en el mismo contexto. (recuerde, incluso dentro de una aplicación, muchos UUID no tienen que ser únicos en toda la aplicación, solo en el contexto en el que se usan)
66
Entonces, parece que si no necesita que su Guid sea seguro, use la versión 1. Si lo necesita seguro y se siente afortunado (o realmente no se siente desafortunado) use la versión 4.
Vaccano
16

Esa es una pregunta muy general. Una respuesta es: "depende del tipo de UUID que desee generar". Pero una mejor es esta: "Bueno, antes de responder, ¿puede decirnos por qué necesita codificar su propio algoritmo de generación de UUID en lugar de llamar a la funcionalidad de generación de UUID que ofrecen los sistemas operativos más modernos?"

Hacerlo es más fácil y seguro, y dado que probablemente no necesite generar el suyo propio, ¿por qué molestarse en codificar una implementación? En ese caso, la respuesta se convierte en usar lo que sea que proporcione su O / S, lenguaje de programación o marco. Por ejemplo, en Windows, hay CoCreateGuid o UuidCreate o uno de los diversos envoltorios disponibles de los numerosos marcos en uso. En Linux hay uuid_generate .

Si, por alguna razón, absolutamente necesita generar el suyo propio, al menos tenga el buen sentido de mantenerse alejado de generar UUID v1 y v2. Es complicado hacerlo bien. Apéguese, en cambio, a los UUID v3, v4 o v5.

Actualización : en un comentario, mencionas que estás usando Python y haces un enlace a esto . Mirando a través de la interfaz proporcionada, la opción más fácil para usted sería generar un UUID v4 (es decir, uno creado a partir de datos aleatorios) llamando uuid.uuid4().

Si tiene algunos datos que necesita (o puede) hacer hash para generar un UUID, entonces puede usar v3 (que se basa en MD5) o v5 (que se basa en SHA1). Generar un UUID v3 o v5 es simple: primero elija el tipo de UUID que desea generar (probablemente debería elegir v5) y luego elija el espacio de nombres apropiado y llame a la función con los datos que desea usar para generar el UUID. Por ejemplo, si está troquelando una URL, usaría NAMESPACE_URL:

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

Tenga en cuenta que este UUID será diferente del UUID v5 para la misma URL, que se genera así:

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

Una buena propiedad de las URL v3 y v5 es que deberían ser interoperables entre implementaciones. En otras palabras, si dos sistemas diferentes están utilizando una implementación que cumple con RFC4122, ambos (o al menos deberían ) generarán el mismo UUID si todas las demás cosas son iguales (es decir, generarán la misma versión de UUID, con el mismo espacio de nombres y mismos datos) Esta propiedad puede ser muy útil en algunas situaciones (especialmente en escenarios de almacenamiento de contenido direccionable), pero quizás no en su caso particular.

Nik Bougalis
fuente
44
Supongo que es porque OP no preguntó: ¿cómo "codifico [mi] propio algoritmo de generación de UUID en lugar de llamar a la funcionalidad de generación de UUID que proporcionan la mayoría de los sistemas operativos modernos?"
anregen
Aparte de eso, creo que es una buena explicación de UUIDv3 y v5. Vea mi respuesta a continuación sobre por qué creo que v1 puede ser una buena opción.
anregen
¿Qué es NAMESPACE_URL? es una variable que puedo obtener? ¿de donde?
stackdave
@stackdave NAMESPACE_URLes un UUID generalmente igual a 6ba7b811-9dad-11d1-80b4-00c04fd430c8, siguiendo la recomendación hecha en la página 30 de RFC-4122 .
Jamie Ridding
2

La documentación de Postgres describe las diferencias entre UUIDs. Un par de ellos:

V3:

uuid_generate_v3(namespace uuid, name text) - Esta función genera un UUID versión 3 en el espacio de nombres dado usando el nombre de entrada especificado.

V4:

uuid_generate_v4 - Esta función genera un UUID versión 4, que se deriva completamente de números aleatorios.

Eugen Konkov
fuente