Générateur UUID v1

Génère des UUID v1 basés sur le temps avec horodatage intégré

Formater

Quantité:
Note:UUID v1 intègre l'adresse MAC de l'hôte et l'horodatage de génération, ce qui soulève des problèmes de confidentialité pour la plupart des applications modernes. Pour les nouveaux projets, UUID v4 est recommandé sauf si vous avez spécifiquement besoin d'identifiants décodables ordonnés dans le temps.

Qu'est-ce qu'UUID v1 ?

UUID v1 est la version UUID originale, standardisée dans RFC 4122 (2005). Elle génère des identifiants uniques en combinant un horodatage haute précision avec l'adresse MAC de l'hôte générateur, plus une courte séquence d'horloge pour gérer la résolution sous-horodatage.

Comme l'horodatage est intégré, les valeurs UUID v1 du même hôte sont monotoniquement croissantes dans le temps — les rendant naturellement ordonnées. Cela était conçu pour les systèmes distribués où chaque noeud pouvait générer des UUID indépendamment sans coordination.

Aujourd'hui UUID v1 est largement supplanté par UUID v7 (triable, sans divulgation MAC) et UUID v4 (entièrement aléatoire, privé). Il reste utilisé dans des systèmes comme Apache Cassandra et les bases de données distribuées legacy.

Anatomie d'un UUID v1

Une chaîne UUID v1 comme 550e8400-e29b-11d4-a716-446655440000 encode six champs distincts :

ChampTailleDescription
time_low32 bitsChamp bas de 32 bits de l'horodatage grégorien de 60 bits (intervalles de 100 nanosecondes depuis le 15 oct. 1582)
time_mid16 bitsChamp milieu de 16 bits de l'horodatage de 60 bits
time_hi_and_version16 bits12 bits supérieurs de l'horodatage de 60 bits plus le numéro de version de 4 bits (toujours <code>1</code>)
clock_seq_hi_res8 bitsChamp haut de séquence d'horloge de 6 bits combiné avec le marqueur de variante RFC 4122 de 2 bits
clock_seq_low8 bits8 bits inférieurs de la séquence d'horloge
node48 bitsIdentifiant de noeud de 48 bits — généralement l'adresse MAC de l'interface réseau génératrice, ou une valeur aléatoire de 48 bits si aucune MAC n'est disponible

Le champ de séquence d'horloge (clock_seq_hi_res + clock_seq_low) est un compteur de 14 bits. Il est incrémenté chaque fois que l'horloge système recule (ex. ajustement NTP) ou lors du redémarrage du système sans persister le dernier horodatage connu. Cela empêche la génération de UUID en double si l'horloge n'avance pas de manière monotone.

Décodage de l'horodatage UUID v1

L'horodatage de 60 bits est dispersé dans trois champs de l'UUID. Pour reconstruire le temps de génération :

  1. Extraire time_low (octets 0-3), time_mid (octets 4-5) et time_hi (octets 6-7, moins le nibble de version)
  2. Réassembler : (time_hi &lt;&lt; 48) | (time_mid &lt;&lt; 32) | time_low
  3. Le résultat est un compte de 60 bits d<code>intervalles de 100 nanosecondes</code> depuis le 15 octobre 1582 (lepoch du calendrier grégorien)
  4. Soustraire l'offset grégorien-vers-Unix : 122 192 928 000 000 000 (intervalles de 100 ns entre le 15 oct. 1582 et le 1er jan. 1970)
  5. Diviser par 10 000 pour convertir les intervalles de 100 nanosecondes en millisecondes
  6. Utiliser le résultat comme horodatage Unix en millisecondes pour construire un objet Date
  7. Formater en ISO 8601 pour une sortie lisible par l'humain

La précision de l'horodatage est de 100 nanosecondes — bien plus fine que la précision milliseconde d'UUID v7. Cependant, en pratique, la plupart des systèmes d'exploitation n'exposent pas une résolution d'horloge sous-milliseconde, donc les bits inférieurs sont souvent à zéro ou synthétisés.

Problèmes de confidentialité

L'inconvénient le plus significatif d'UUID v1 est qu'il intègre l'adresse MAC de l'hôte générateur dans le champ node. Cela signifie que chaque UUID v1 porte une empreinte permanente et globalement unique de la machine qui l'a généré.

Un adversaire qui obtient un UUID v1 peut déterminer : (1) le temps approximatif où l'identifiant a été généré, (2) l'adresse MAC de l'hôte générateur, et (3) en analysant plusieurs UUID, le taux auquel les identifiants sont générés.

Pour cette raison, UUID v1 ne devrait jamais être utilisé comme identifiant public (ex. dans les URL ou les réponses d'API) sauf si vous êtes à l'aise de divulguer ces informations. RFC 4122 lui-même note qu'un système peut utiliser une valeur aléatoire de 48 bits à la place de l'adresse MAC, mais de nombreuses implémentations ne le font pas.

Quand UUID v1 est encore approprié

Clés primaires Apache Cassandra
Cassandra utilise UUID v1 (via le type TimeUUID) comme modèle de conception fondamental. L'ordre par horodatage se mappe naturellement au modèle de stockage de Cassandra, permettant des requêtes efficaces sur des plages de temps.
Systèmes distribués legacy
Systèmes construits avant l'existence d'UUID v7 (pré-2024) qui reposent sur des UUID ordonnés par horodatage et ne peuvent pas facilement migrer vers un nouveau format.
Journaux d'audit et d'événements
Quand l'identité de l'hôte générateur est connue et de confiance, l'intégration de l'adresse MAC peut fournir une traçabilité supplémentaire pour les événements d'audit.
Identifiants internes
Identifiants qui ne sont jamais exposés en dehors d'un système interne contrôlé, où la divulgation de l'adresse MAC n'est pas une préoccupation.
Requêtes sur des plages de temps sans colonne d'horodatage séparée
L'horodatage intégré peut être décodé pour filtrer les lignes par temps de génération, servant d'identifiant et d'horodatage combinés.
Interopérabilité avec les anciens générateurs UUID v1
Lors de la réception ou du traitement de valeurs UUID v1 provenant de systèmes externes qui les produisent, le décodage de l'horodatage intégré pour l'affichage ou l'analyse.

UUID v1 vs UUID v7

UUID v7 est le successeur moderne d'UUID v1 pour les identifiants ordonnés dans le temps. Voici une comparaison directe :

AspectUUID v1UUID v7
Epoch / Base temporelleEpoch grégorien (15 oct. 1582)Epoch Unix (1er jan. 1970)
Précision100 nanosecondes1 milliseconde
Identifiant de noeudAdresse MAC (divulgue l'identité de l'hôte)Aléatoire (privé)
ConfidentialitéDivulgue l'adresse MAC et l'horodatage de générationAucune information sur l'hôte intégrée
Performance d'index BDBonne — séquentielle par hôteExcellente — k-sortable sur tous les générateurs
StandardRFC 4122 (2005)RFC 9562 (2024)

Pour les nouveaux projets, UUID v7 est le remplacement recommandé pour UUID v1. Il fournit des garanties similaires d'ordre temporel sans les implications de confidentialité liées à l'intégration de l'adresse MAC de l'hôte.

Exemples de code

La génération UUID v1 n'est pas disponible nativement dans les navigateurs ou Node.js. Utilisez le package 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))
}

Foire Aux Questions

Puis-je décoder l'horodatage d'un UUID v1 ?
Oui. L'horodatage de génération est entièrement récupérable à partir d'une chaîne UUID v1. Cet outil fait exactement cela — collez n'importe quel UUID v1 et il affichera l'horodatage UTC décodé. Voir les étapes de décodage ci-dessus pour l'algorithme.
L'adresse MAC est-elle toujours présente dans UUID v1 ?
Pas nécessairement. RFC 4122 permet aux implémentations de substituer une valeur aléatoire de 48 bits à l'adresse MAC quand aucune interface réseau n'est disponible ou quand la confidentialité est souhaitée. En pratique, de nombreuses implémentations côté serveur intègrent bien la vraie adresse MAC. Les valeurs UUID v1 générées dans le navigateur utilisent toujours une valeur de noeud aléatoire car les navigateurs n'exposent pas les adresses MAC.
Pourquoi l'horodatage UUID v1 utilise-t-il 1582 comme epoch ?
La réforme du calendrier grégorien est entrée en vigueur le 15 octobre 1582. L'horodatage UUID v1 a été défini par rapport à cette date pour fournir un point de référence stable et universel antérieur à l'epoch Unix (1970). Cela donne au champ d'horodatage de 60 bits suffisamment de portée pour rester unique jusqu'à environ l'an 3400.
UUID v1 vs UUID v7 — quand utiliser encore v1 ?
La principale raison d'utiliser UUID v1 aujourd'hui est la compatibilité avec les systèmes existants — en particulier Apache Cassandra, qui utilise v1 comme son type TimeUUID. Pour tous les nouveaux systèmes, UUID v7 est strictement meilleur : il utilise l'epoch Unix plus familier, n'a pas de divulgation d'adresse MAC et offre de meilleures performances d'index B-tree.
Les valeurs UUID v1 peuvent-elles entrer en collision ?
En théorie, deux valeurs UUID v1 peuvent entrer en collision si la même adresse MAC génère deux UUID dans le même intervalle de 100 nanosecondes et que la séquence d'horloge est identique. La séquence d'horloge existe précisément pour empêcher cela — elle est incrémentée lors d'appels successifs rapides. En pratique, les collisions UUID v1 sont extrêmement rares dans les systèmes correctement implémentés.