Generador UUID v1

Genera UUID v1 basados en tiempo con marca temporal integrada

Formatear

Cantidad:
Note:UUID v1 incorpora la dirección MAC del host y la marca de tiempo de generación, lo que plantea problemas de privacidad para la mayoría de las aplicaciones modernas. Para proyectos nuevos, se recomienda UUID v4 a menos que necesite específicamente identificadores decodificables ordenados por tiempo.

¿Qué es UUID v1?

UUID v1 es la versión original de UUID, estandarizada en RFC 4122 (2005). Genera identificadores únicos combinando una marca de tiempo de alta precisión con la dirección MAC del host generador, más una secuencia de reloj corta para manejar la resolución por debajo de la marca de tiempo.

Debido a que la marca de tiempo está incorporada, los valores UUID v1 del mismo host son monótonamente crecientes con el tiempo, lo que los hace ordenados de forma natural. Esto fue diseñado para sistemas distribuidos donde cada nodo podía generar UUIDs de forma independiente sin coordinación.

Hoy UUID v1 es ampliamente reemplazado por UUID v7 (ordenable, sin filtrado de MAC) y UUID v4 (completamente aleatorio, privado). Permanece en uso en sistemas como Apache Cassandra y bases de datos distribuidas heredadas.

Anatomía de un UUID v1

Una cadena UUID v1 como 550e8400-e29b-11d4-a716-446655440000 codifica seis campos distintos:

CampoTamañoDescripción
time_low32 bitsCampo de 32 bits de bajo orden de la marca de tiempo gregoriana de 60 bits (intervalos de 100 nanosegundos desde el 15 de oct. de 1582)
time_mid16 bitsCampo de 16 bits del medio de la marca de tiempo de 60 bits
time_hi_and_version16 bits12 bits superiores de la marca de tiempo de 60 bits más el número de versión de 4 bits (siempre <code>1</code>)
clock_seq_hi_res8 bitsCampo de 6 bits de alto orden de la secuencia de reloj combinado con el marcador de variante RFC 4122 de 2 bits
clock_seq_low8 bits8 bits inferiores de la secuencia de reloj
node48 bitsIdentificador de nodo de 48 bits — típicamente la dirección MAC de la interfaz de red generadora, o un valor aleatorio de 48 bits si no hay MAC disponible

El campo de secuencia de reloj (clock_seq_hi_res + clock_seq_low) es un contador de 14 bits. Se incrementa cada vez que el reloj del sistema retrocede (p. ej. ajuste de NTP) o cuando el sistema se reinicia sin persistir la última marca de tiempo conocida. Esto previene la generación de UUIDs duplicados si el reloj no avanza de forma monótona.

Decodificando la Marca de Tiempo de UUID v1

La marca de tiempo de 60 bits está distribuida en tres campos del UUID. Para reconstruir el tiempo de generación:

  1. Extraiga time_low (bytes 0–3), time_mid (bytes 4–5) y time_hi (bytes 6–7, menos el nibble de versión)
  2. Reensamblar: (time_hi &lt;&lt; 48) | (time_mid &lt;&lt; 32) | time_low
  3. El resultado es un conteo de 60 bits de intervalos de 100 nanosegundos desde el 15 de octubre de 1582 (la época del calendario gregoriano)
  4. Reste el desplazamiento gregoriano-a-Unix: 122.192.928.000.000.000 (intervalos de 100 ns entre el 15 oct. 1582 y el 1 ene. 1970)
  5. Divida entre 10.000 para convertir intervalos de 100 nanosegundos a milisegundos
  6. Use el resultado como una marca de tiempo Unix en milisegundos para construir un objeto Date
  7. Formatee como ISO 8601 para salida legible por humanos

La precisión de la marca de tiempo es de 100 nanosegundos — mucho más fina que la precisión de milisegundos de UUID v7. Sin embargo, en la práctica la mayoría de los sistemas operativos no exponen resolución de reloj por debajo del milisegundo, por lo que los bits inferiores suelen ser cero o sintéticos.

Problemas de Privacidad

El inconveniente más significativo de UUID v1 es que incorpora la dirección MAC del host generador en el campo de nodo. Esto significa que cada UUID v1 lleva una huella digital permanente y globalmente única de la máquina que lo generó.

Un adversario que obtiene un UUID v1 puede determinar: (1) el tiempo aproximado en que se generó el ID, (2) la dirección MAC del host generador, y (3) analizando múltiples UUIDs, la tasa a la que se están generando IDs.

Por esta razón, UUID v1 nunca debería usarse como identificador público (p. ej. en URLs o respuestas de API) a menos que esté cómodo divulgando esta información. El propio RFC 4122 señala que un sistema puede usar un valor aleatorio de 48 bits en lugar de la dirección MAC, pero muchas implementaciones no lo hacen.

Cuándo UUID v1 Sigue Siendo Apropiado

Claves primarias de Apache Cassandra
Cassandra usa UUID v1 (mediante el tipo TimeUUID) como patrón de diseño central. El ordenamiento por marca de tiempo se mapea naturalmente al modelo de almacenamiento de Cassandra, habilitando consultas eficientes por rango de tiempo.
Sistemas distribuidos heredados
Sistemas construidos antes de que existiera UUID v7 (antes de 2024) que dependen de UUIDs ordenados por marca de tiempo y no pueden migrar fácilmente a un nuevo formato.
Registros de auditoría y eventos
Cuando la identidad del host generador es conocida y confiable, incorporar la dirección MAC puede proporcionar rastreabilidad adicional para eventos de auditoría.
Identificadores internos
IDs que nunca se exponen fuera de un sistema interno controlado, donde la divulgación de la dirección MAC no es una preocupación.
Consultas por rango de tiempo sin una columna de marca de tiempo separada
La marca de tiempo incorporada puede decodificarse para filtrar filas por tiempo de generación, actuando como un ID y marca de tiempo combinados.
Interoperabilidad con generadores UUID v1 más antiguos
Al recibir o procesar valores UUID v1 de sistemas externos que los producen, decodificando la marca de tiempo incorporada para visualización o análisis.

UUID v1 vs UUID v7

UUID v7 es el sucesor moderno de UUID v1 para identificadores ordenados por tiempo. Aquí hay una comparación directa:

AspectoUUID v1UUID v7
Época / Base de TiempoÉpoca gregoriana (15 oct. 1582)Época Unix (1 ene. 1970)
Precisión100 nanosegundos1 milisegundo
Identificador de NodoDirección MAC (filtra identidad del host)Aleatorio (privado)
PrivacidadFiltra dirección MAC y marca de tiempo de generaciónSin información del host incorporada
Rendimiento de índice BDBueno — secuencial por hostExcelente — k-ordenable entre todos los generadores
EstándarRFC 4122 (2005)RFC 9562 (2024)

Para proyectos nuevos, UUID v7 es el reemplazo recomendado para UUID v1. Proporciona garantías similares de ordenación temporal sin las implicaciones de privacidad de incorporar la dirección MAC del host.

Ejemplos de Código

La generación de UUID v1 no está disponible de forma nativa en navegadores o Node.js. Use el paquete npm uuid:

JavaScript (browser)
// Generate a UUID v1 using the Web Crypto API
function generateUuidV1() {
  const buf = new Uint8Array(16)
  crypto.getRandomValues(buf)

  const ms = BigInt(Date.now())
  const gregorianOffset = 122192928000000000n
  const t = ms * 10000n + gregorianOffset

  const tLow   = Number(t & 0xFFFFFFFFn)
  const tMid   = Number((t >> 32n) & 0xFFFFn)
  const tHiVer = Number((t >> 48n) & 0x0FFFn) | 0x1000  // version 1

  const clockSeq    = (buf[8] & 0x3F) | 0x80  // variant 10xxxxxx
  const clockSeqLow = buf[9]

  const hex  = (n, pad) => n.toString(16).padStart(pad, '0')
  const node = [...buf.slice(10)].map(b => b.toString(16).padStart(2, '0')).join('')

  return `${hex(tLow,8)}-${hex(tMid,4)}-${hex(tHiVer,4)}-${hex(clockSeq,2)}${hex(clockSeqLow,2)}-${node}`
}

// Extract the embedded timestamp from a UUID v1
function extractTimestamp(uuid) {
  const parts = uuid.split('-')
  const tHex = parts[2].slice(1) + parts[1] + parts[0]
  const t = BigInt('0x' + tHex)
  const ms = (t - 122192928000000000n) / 10000n
  return new Date(Number(ms))
}

const id = generateUuidV1()
console.log(id)                      // e.g. "1eb5e8b0-6b4d-11ee-9c45-a1f2b3c4d5e6"
console.log(extractTimestamp(id))    // e.g. 2023-10-15T12:34:56.789Z
Python
import uuid
from datetime import datetime, timezone

# Generate UUID v1 (uses MAC address by default)
uid = uuid.uuid1()
print(uid)

# Extract embedded timestamp
# uuid.time is 100-ns intervals since Oct 15, 1582
GREGORIAN_OFFSET = 122192928000000000  # 100-ns intervals
ts_100ns = uid.time
ts_ms = (ts_100ns - GREGORIAN_OFFSET) // 10000
dt = datetime.fromtimestamp(ts_ms / 1000, tz=timezone.utc)
print(dt.isoformat())   # e.g. "2023-10-15T12:34:56.789000+00:00"
Go
package main

import (
    "fmt"
    "time"

    "github.com/google/uuid"  // go get github.com/google/uuid
)

func main() {
    id, _ := uuid.NewUUID()  // UUID v1
    fmt.Println(id)

    // Extract timestamp from UUID v1
    // uuid.Time is 100-ns ticks since Oct 15, 1582
    t := id.Time()
    sec  := int64(t)/1e7 - 12219292800  // convert to Unix seconds
    nsec := (int64(t) % 1e7) * 100
    ts   := time.Unix(sec, nsec).UTC()
    fmt.Println(ts.Format(time.RFC3339Nano))
}

Preguntas Frecuentes

¿Puedo decodificar la marca de tiempo de un UUID v1?
Sí. La marca de tiempo de generación es totalmente recuperable de una cadena UUID v1. Esta herramienta hace exactamente eso — pegue cualquier UUID v1 y mostrará la marca de tiempo UTC decodificada. Vea los pasos de decodificación anteriores para el algoritmo.
¿Está siempre presente la dirección MAC en UUID v1?
No necesariamente. RFC 4122 permite que las implementaciones sustituyan un valor aleatorio de 48 bits por la dirección MAC cuando no hay interfaz de red disponible o cuando se desea privacidad. En la práctica, muchas implementaciones del lado del servidor sí incorporan la dirección MAC real. Los valores UUID v1 generados en el navegador siempre usan un valor de nodo aleatorio ya que los navegadores no exponen las direcciones MAC.
¿Por qué la marca de tiempo de UUID v1 usa 1582 como época?
La reforma del calendario gregoriano entró en vigor el 15 de octubre de 1582. La marca de tiempo de UUID v1 se definió en relación con esta fecha para proporcionar un punto de referencia estable y universal anterior a la época Unix (1970). Esto le da al campo de marca de tiempo de 60 bits suficiente rango para permanecer único hasta aproximadamente el año 3400 d.C.
UUID v1 vs UUID v7 — ¿cuándo debería seguir usando v1?
La razón principal para usar UUID v1 hoy es la compatibilidad con sistemas existentes — particularmente Apache Cassandra, que usa v1 como su tipo TimeUUID. Para todos los sistemas nuevos, UUID v7 es estrictamente mejor: usa la época Unix más familiar, no tiene filtrado de dirección MAC y proporciona mejor rendimiento de índice B-tree.
¿Pueden colisionar los valores UUID v1?
En teoría, dos valores UUID v1 pueden colisionar si la misma dirección MAC genera dos UUIDs dentro del mismo intervalo de 100 nanosegundos y la secuencia de reloj es idéntica. La secuencia de reloj existe precisamente para prevenir esto — se incrementa en llamadas sucesivas rápidas. En la práctica, las colisiones de UUID v1 son extremadamente raras en sistemas correctamente implementados.