Generador de UUID
Genera UUID uno a uno o cincuenta a la vez: v4 aleatorios, o v7 ordenados por tiempo, cuya marca temporal ordena el lote y sirve de clave de base de datos.
122 bits aleatorios. No revela nada sobre cuándo se creó.
Generando…
Qué es un UUID y por qué existe
Un UUID —Universally Unique Identifier, llamado GUID en la documentación de Microsoft— es un valor de 128 bits escrito como 32 dígitos hexadecimales en la familiar agrupación 8-4-4-4-12. Su propósito entero es permitir que sistemas separados acuñen identificadores de forma independiente, sin coordinación alguna entre ellos, y aun así confiar en que los resultados no colisionarán. Eso es lo que lo distingue de una columna autoincremental: dos servidores, dos clientes móviles sin conexión en un avión y un proceso en segundo plano pueden crear registros en el mismo instante sin pedirle permiso a nadie.
La unicidad aquí es probabilística, no garantizada. La versión 4 deja 122 bits al azar, un espacio lo bastante grande como para que, incluso generando miles de millones de valores, la probabilidad de una repetición siga estando muy por debajo de la de que un disco corrompa los datos en silencio. En la práctica puedes tratarlo como único; las matemáticas no son el eslabón débil.
Versión 4 frente a versión 7: la decisión que importa
La versión 4 es aleatoria de principio a fin. No transporta información alguna: ni cuándo se creó, ni por quién, ni en qué orden. Esa es su mayor virtud o su defecto central, según dónde la pongas.
La versión 7, estandarizada en el RFC 9562 en 2024, sustituye los primeros 48 bits por una marca de tiempo Unix en milisegundos y rellena el resto con aleatoriedad. Como el tiempo va primero y el valor se lee de izquierda a derecha, ordenar identificadores v7 como texto plano también los ordena cronológicamente.
No es una diferencia cosmética. Las bases de datos guardan las claves primarias en un índice B-tree ordenado. Si insertas claves v7, cada fila nueva aterriza en el borde derecho del árbol, junto a la anterior: las páginas en las que escribes permanecen en memoria y el índice crece ordenadamente. Si insertas claves v4, cada escritura cae en una posición aleatoria, la base de datos toca una página distinta cada vez, la tasa de aciertos en caché baja y el índice se fragmenta. En una tabla grande y con mucho tráfico la diferencia de rendimiento en las inserciones es considerable, y por eso v7 se ha adoptado tan rápido para claves primarias.
- Elige v7 para claves primarias, identificadores de eventos y registros, y todo aquello que vayas a ordenar o consultar por rango de fecha de creación.
- Elige v4 cuando el identificador aparezca en un lugar no confiable y no deba filtrar nada, ni siquiera que un registro se creó justo antes que otro.
- Cualquiera de las dos sirve para un ID de correlación, una clave de idempotencia o un nombre de archivo, donde el orden no importa.
La contrapartida es exactamente esa filtración: un identificador v7 le dice a cualquiera que lo vea, al milisegundo, cuándo se creó. Para el ID de una fila eso suele ser inofensivo y a menudo útil. Para un token de restablecimiento de contraseña o un enlace público para compartir es información que no pretendías publicar, y esos no deberían ser UUID en absoluto, sino tokens aleatorios de un generador de secretos específico.
El orden dentro del mismo milisegundo
Una sutileza que se le escapa a muchas implementaciones de v7: el hardware moderno genera muchos más de un identificador por milisegundo. Si dos valores comparten marca de tiempo, su orden lo deciden los bits aleatorios que vienen después, es decir, al azar. Genera cincuenta en un bucle cerrado y obtendrás cincuenta valores solo aproximadamente ordenados, perdiendo justo la propiedad por la que elegiste v7.
El RFC 9562 lo resuelve con un contador monótono, y esta herramienta lo implementa: los 12 bits inmediatamente posteriores a la marca de tiempo cuentan hacia arriba dentro de un milisegundo, de modo que un lote es estrictamente creciente y no solo aproximado. Si el contador se llena —más de 4096 valores en el mismo milisegundo— el generador toma prestado el milisegundo siguiente en lugar de dar la vuelta y emitir un valor que se ordene antes que su predecesor. El reloj yendo hacia atrás, algo que ocurre con las correcciones NTP, se trata igual.
Leyendo un valor v7 de izquierda a derecha, tomando 0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b como ejemplo:
- 0190a1b2-c3d4 — la marca de tiempo Unix de 48 bits en milisegundos. Como va primero, el orden textual es el orden temporal.
- 7 — el dígito de versión, que es lo que hace que esto sea un v7 y no un v4.
- e5f — el contador monótono de 12 bits, que se incrementa dentro de un mismo milisegundo.
- 8 — los bits de variante, fijados por el RFC 9562 para todo UUID moderno (siempre 8, 9, a o b).
- a9b-0c1d2e3f4a5b — los 62 bits restantes, puramente aleatorios.
Almacenar y usar UUID
La forma canónica es en minúsculas y con guiones, y el RFC 9562 dice que los generadores deben emitir exactamente eso, razón por la que esta herramienta no ofrece opciones de formato. Aun así te encontrarás otras grafías: en mayúsculas y entre llaves en las herramientas de Microsoft, y sin guiones donde alguien quiso una columna más corta. Todas son los mismos 128 bits, y las comparaciones deberían ignorar mayúsculas y minúsculas.
Donde de verdad cuenta es en el almacenamiento. Un UUID son 16 bytes, pero su forma textual son 36 caracteres, así que guardarlo como cadena más que duplica el espacio en la fila y, más importante, en todos los índices que lo incluyan. Usa un tipo nativo donde exista:
uuid -- PostgreSQL: tipo nativo de 16 bytes BINARY(16) -- MySQL: compacto; CHAR(36) desperdicia 20 bytes por fila uniqueidentifier -- SQL Server crypto.randomUUID() // JavaScript: solo v4, requiere contexto seguro uuid.uuid4() / uuid7() # Python: v4 en la biblioteca estándar; v7 con una biblioteca
Una última advertencia: un UUID identifica, no autoriza. Como no se pueden adivinar, resulta tentador tratar una URL no listada que contenga uno como si fuera privada. Pero los identificadores se filtran —por registros, historial del navegador, cabeceras referrer y capturas de pantalla—, así que todo lo que realmente necesite protección sigue necesitando una comprobación de permisos detrás.
Cómo saber si un UUID es v4 o v7
Normalmente te llega un identificador sin ninguna nota que diga de dónde salió, y no hace falta: la versión está escrita dentro del propio valor. Ambas son 32 dígitos hexadecimales en la misma agrupación 8-4-4-4-12, así que la diferencia no está en la forma, sino en dos dígitos sueltos en posiciones fijas, y todo lo demás se deduce de ellos.
- El primer dígito del tercer grupo es el dígito de versión. Un 4 ahí significa versión 4, un 7 significa versión 7, y ninguna otra parte del valor tiene voz en ello.
- El primer dígito del cuarto grupo lleva los bits de variante y es 8, 9, a o b en ambas versiones, así que nunca te dice cuál tienes delante. Lo que sí te dice es que el valor sigue el RFC 9562: cualquier otra cosa en esa posición es una disposición más antigua o no es un UUID.
- Si el dígito de versión es un 7, los doce primeros dígitos son la hora de creación: una cuenta de 48 bits de milisegundos desde el principio de 1970, escrita en hexadecimal.
- Si es un 4, no hay nada más que leer. Un v4 no codifica ni hora, ni máquina, ni orden, que es justo la propiedad por la que lo elegiste.
Toma el valor que desglosa la sección anterior, 0190a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b. Su tercer grupo empieza por 7, así que es una versión 7, y sus doce primeros dígitos son 0190a1b2c3d4: convierte ese número hexadecimal a decimal, dáselo al Conversor de marca de tiempo Unix y obtendrás una tarde de julio de 2024. A su lado, 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d empieza su tercer grupo por 4, y sus propios doce primeros dígitos son datos aleatorios que no descodifican a nada. Los dos coinciden exactamente en una cosa: ambos empiezan su cuarto grupo por uno de los cuatro dígitos que permiten los bits de variante.
¿Es v7 tan resistente a colisiones como v4?
Es una duda razonable, porque v7 lleva de verdad menos aleatoriedad. La versión 4 dedica 122 de sus 128 bits a datos aleatorios. La versión 7 dedica 48 a la marca de tiempo y, aquí, 12 más al contador monótono, con lo que quedan 62 bits aleatorios: algo más de la mitad. Leído como número desnudo parece un retroceso serio.
- Dentro de un mismo lote de esta herramienta una repetición no es improbable, sino imposible. Los valores que comparten milisegundo reciben valores de contador distintos, y los que no lo comparten llevan marcas de tiempo distintas, así que no puede haber dos iguales: es aritmética, no probabilidad.
- Entre dos máquinas que generan en el mismo instante, las probabilidades son a lo sumo el problema del cumpleaños sobre 62 bits, que se iguala más o menos en la raíz cuadrada del espacio: del orden de dos mil millones de valores, y todos en un mismo y único milisegundo.
- Entre milisegundos distintos una colisión de v7 no es solo improbable, sino imposible, porque los propios dígitos iniciales difieren.
Así que la comparación honesta no es 122 bits contra 62. Es una lotería que se sortea una y otra vez durante toda la vida del sistema frente a una lotería aparte y mucho menor que se celebra dentro de cada milisegundo y se tira cuando el milisegundo termina. La segunda disposición es la más fuerte, y la razón para preferir v4 sigue siendo la que da la sección de la comparación: no las colisiones, sino que un v7 dice en voz alta cuándo se creó.
Pasar una tabla existente de v4 a v7
La pregunta que sigue a elegir v7 es qué hacer con las filas que ya están en la tabla, y lo tranquilizador es que la columna no tiene que cambiar en absoluto. Ambas versiones son los mismos 128 bits en la misma forma textual de 36 caracteres, así que una columna uuid de PostgreSQL, un BINARY(16) o un CHAR(36) guardan una mezcla sin enterarse. Empiezas a generar v7 para las filas nuevas y ahí acaba todo: no hay paso de migración ni relleno hacia atrás.
- Lo que llegas a tener enseguida: toda fila insertada a partir de ahora lleva una marca de tiempo delante, así que las claves nuevas aterrizan juntas en un extremo del índice en lugar de dispersarse por él. Ese beneficio es sobre adónde van las escrituras nuevas, y está ahí desde la primera inserción.
- Lo que no llega nunca: las filas que ya están se quedan sin orden para siempre. Nada puede meter una hora de creación en un valor al que nunca se le dio una, y volver a emitir cada identificador significa reescribir cada clave foránea que apunte a él, un trabajo mucho mayor que cambiar de generador y que rara vez compensa solo por el índice.
- A qué prestar atención: ordenar la columna deja de significar una sola cosa. Una cuenta de milisegundos es un número pequeño para un campo de 48 bits, así que las claves v7 se agrupan en una banda estrecha en la parte baja del rango mientras que las v4 están repartidas por todo él, y de vez en cuando una cae entre medias.
Ese último punto es el que muerde, porque una consulta que ordena por la clave parece correcta sobre los datos nuevos y falsea en silencio los viejos. Si necesitas un solo orden sobre toda la tabla, añade una columna con la hora de creación y ordena por ella, y deja que el identificador vuelva a ser un identificador. Al menos la mezcla se puede leer mientras tanto: el dígito de versión está en cada valor, así que una consulta puede distinguir las dos épocas sin una segunda columna cuando le hace falta.
Preguntas frecuentes
- ¿Debería usar v4 o v7?
- Usa v7 para claves primarias y todo lo que vayas a ordenar por fecha de creación: la marca de tiempo inicial mantiene las inserciones agrupadas al final del índice en lugar de dispersas por él. Usa v4 cuando el identificador no deba revelar nada en absoluto, ni siquiera cuándo se creó.
- ¿Pueden repetirse dos UUID?
- Es posible, pero increíblemente improbable. La versión 4 tiene 122 bits aleatorios, así que incluso tras generar miles de millones de valores la probabilidad de colisión sigue muy por debajo de la de que el almacenamiento los corrompa en silencio.
- ¿Qué pasó con las versiones 1, 3 y 5?
- La versión 1 codifica una marca de tiempo y la dirección MAC de la máquina, lo que filtra la identidad del hardware y ni siquiera puede producirse en un navegador. Las versiones 3 y 5 derivan un UUID de forma determinista a partir de un espacio de nombres y un nombre usando MD5 o SHA-1: útil cuando la misma entrada debe dar siempre el mismo identificador, pero es otra tarea distinta de generar uno nuevo.
- ¿Es un UUID lo bastante seguro como token secreto?
- Un UUID v4 no se puede adivinar, pero uno v7 codifica abiertamente su hora de creación, y ninguno está pensado como credencial. Para restablecimientos de contraseña, tokens de sesión o enlaces compartidos, genera un secreto aleatorio específico y comprueba permisos en el servidor en vez de confiar en que el identificador sea difícil de adivinar.
- ¿Por qué mi lote de v7 no sale perfectamente ordenado en otras herramientas?
- Porque muchas implementaciones se saltan el contador monótono. Cuando varios valores comparten milisegundo, su orden queda en manos de los bits aleatorios que siguen. Esta herramienta implementa el contador del RFC 9562, así que un lote generado aquí es estrictamente creciente.
- ¿Cómo debería guardar un UUID en una base de datos?
- En un tipo nativo de 16 bytes donde exista: uuid en PostgreSQL, uniqueidentifier en SQL Server, BINARY(16) en MySQL. Guardar en su lugar la forma textual de 36 caracteres más que duplica el espacio usado en la fila y en cada índice que incluya la columna.
- ¿Se generan en vuestros servidores?
- No. Se generan en tu navegador con crypto.getRandomValues, la fuente criptográfica de aleatoriedad de la plataforma, la misma que usa crypto.randomUUID. Ningún valor se envía a ninguna parte, y recargar la página produce un conjunto completamente nuevo.
- ¿Se puede saber cuándo se creó un UUID v7?
- Sí, y no necesitas nada más que el valor. Sus doce primeros dígitos hexadecimales son una cuenta de milisegundos desde el principio de 1970: conviértelos a decimal y dale el resultado al Conversor de marca de tiempo Unix. Un v4 no tiene ese campo, así que ahí esos mismos doce dígitos son aleatorios y no descodifican a nada.
- ¿Tiene v7 menos bits aleatorios que v4?
- Sí: 62 aquí frente a los 122 de v4, porque la marca de tiempo y el contador ocupan el sitio. En la práctica eso no hace más probable una colisión: dos valores v7 solo pueden colisionar si se crearon en el mismo milisegundo, así que esos 62 bits se gastan dentro de un milisegundo y no a lo largo de toda la vida del sistema, y dentro de un mismo lote de esta herramienta el contador hace que una repetición sea imposible en vez de simplemente improbable.
- ¿Pueden convivir UUID v4 y v7 en la misma columna?
- Sí. Son los mismos 128 bits en la misma forma textual, así que en el esquema no cambia nada y no hay migración: generas v7 a partir de ahora y dejas en paz las filas viejas. Lo único a vigilar es la ordenación: las filas nuevas quedan entre sí en orden de creación, pero las viejas aleatorias están repartidas alrededor, así que ordenar por la clave no es un orden temporal para la tabla en conjunto.
- ¿Qué son las versiones 6 y 8 de UUID?
- El RFC 9562 define ambas junto a v7. La versión 6 es la versión 1 con los campos de la marca de tiempo reordenados para que el valor se ordene cronológicamente, y está pensada para sistemas ya comprometidos con v1: el RFC dice que cualquier otro caso debería usar v7. La versión 8 es un hueco deliberadamente abierto para disposiciones propias, en el que solo quedan fijos los bits de versión y de variante y los 122 restantes los defines tú. Esta herramienta no genera ninguna de las dos.
Herramientas relacionadas
- Generador de tokens
Genera claves, secretos y frases de contraseña seguras.
- Generador de datos de prueba
Datos de prueba con semilla, con dígitos de control e IBAN realmente válidos.
- Generador de códigos QR
Cada decisión de codificación a la vista: modo, versión, nivel y máscara.