Generatore UUID v2
Genera UUID v2 DCE Security con dominio locale e ID
Cos'è UUID v2?
UUID v2 è la versione UUID per la sicurezza DCE, standardizzata come parte della specifica Distributed Computing Environment (DCE) e referenziata in RFC 4122. Estende UUID v1 incorporando un identificatore di utente o gruppo POSIX (UID/GID) nel campo timestamp.
La struttura è simile a UUID v1, ma il campo time_low a 32 bit è sostituito da un identificatore locale a 32 bit (es. un UID POSIX) e un campo local_domain di 1 byte identifica il tipo di ID locale. Il timestamp è troncato di conseguenza, riducendo la sua precisione e le garanzie di unicità.
UUID v2 è estremamente raro nel software moderno. La maggior parte degli sviluppatori non avrà mai bisogno di generarne uno. Questa pagina documenta il formato per completezza e per aiutare nella decodifica dei valori UUID v2 incontrati in sistemi legacy.
Struttura UUID v2
Un UUID v2 ha lo stesso formato a 128 bit con trattini degli altri versioni UUID. I campi differiscono da UUID v1 come segue:
| Campo | Bit | Scopo |
|---|---|---|
| local_id | 32 | <code>local_id</code> — identificatore di dominio locale a 32 bit (es. UID POSIX da <code>/etc/passwd</code>), sostituisce il campo time_low di UUID v1 |
| time_mid | 16 | <code>time_mid</code> — 16 bit centrali del timestamp UUID v1 troncato |
| time_hi+version | 16 | <code>time_hi_and_version</code> — i 12 bit superiori del timestamp con nibble di versione impostato a <code>2</code> |
| variant+clock_hi | 8 | <code>clock_seq_hi_and_reserved</code> — bit di variante più la porzione alta della sequenza di clock |
| local_domain | 8 | <code>local_domain</code> — identificatore di dominio: <code>0</code> = Utente POSIX (UID), <code>1</code> = Gruppo POSIX (GID), <code>2</code> = Organizzazione |
| node | 48 | <code>node</code> — indirizzo MAC a 48 bit dell'host generatore |
Esempio: 000003e8-92e0-21ef-8000-325096b39f47 — local_id 0x000003e8 = UID 1000, local_domain 0x00 = Utente POSIX
Valori del dominio locale
Il byte local_domain specifica il tipo di identificatore locale incorporato nell'UUID:
I valori di dominio sono definiti dalla specifica DCE. I valori 3-255 sono riservati. In pratica, solo il dominio 0 (Persona/UID) è comunemente incontrato nei valori UUID v2 reali.
Perché UUID v2 è raramente usato
Tre caratteristiche rendono UUID v2 impraticabile per la maggior parte delle applicazioni moderne:
Risoluzione timestamp grossolana
Il timestamp è troncato a 28 bit (circa granularità di 7,2 minuti). In quella finestra, gli UUID generati con lo stesso local_id e dominio sullo stesso host non sono univoci — la specifica si affida al campo clock_seq per differenziarli, limitando l'unicità a 64 valori per finestra di 7 minuti.
Nessun supporto di libreria standard
A differenza di UUID v1 e v4, UUID v2 non è supportato dalla maggior parte delle librerie UUID. Il pacchetto npm uuid, il modulo Python uuid e java.util.UUID di Java omettono tutti v2. È richiesta un'implementazione personalizzata.
Semantica specifica a POSIX
Il concetto di dominio locale (UID/GID) è intrinsecamente specifico a POSIX e non si traduce significativamente a Windows, sistemi embedded o ambienti cloud dove il concetto di ID utente POSIX è assente.
Contesto storico
UUID v2 è stato definito come parte del Distributed Computing Environment (DCE/RPC) dell'Open Software Foundation all'inizio degli anni '90. L'obiettivo era creare UUID che potessero trasportare il contesto di autorizzazione — specificamente, per permettere a un server RPC di identificare l'utente chiamante senza un passaggio di autenticazione separato.
Il modello di sicurezza DCE presumeva un ambiente POSIX omogeneo dove ogni nodo partecipava a un namespace UID/GID condiviso. L'UID incorporato permetterebbe al server di controllare rapidamente le liste di controllo degli accessi senza un round-trip a un servizio directory.
- Internet si è allontanato dagli ambienti POSIX omogenei verso architetture cloud eterogenee
- L'autenticazione moderna usa token (JWT, OAuth) piuttosto che UID incorporati negli identificatori
- UUID v4 (completamente casuale) e UUID v7 (ordinato nel tempo) coprono i casi d'uso pratici per gli identificatori univoci
- DCE/RPC stesso è caduto in disuso
RFC 4122 (2005) ha incluso UUID v2 per riferimento alla specifica DCE, ma ha deliberatamente omesso l'algoritmo di generazione dettagliato — notando che era definito da DCE piuttosto che dall'IETF.
RFC 9562 (2024), che ha aggiornato lo standard UUID, ha mantenuto UUID v2 per completezza storica ma ha continuato a notare la sua natura specifica a POSIX e l'assenza di un algoritmo di generazione completo nello standard IETF.
UUID v2 vs UUID v1
UUID v2 è derivato da UUID v1. Ecco come si confrontano:
| Aspetto | UUID v1 | UUID v2 |
|---|---|---|
| Bit timestamp | 60 bit (~precisione 100ns) | 28 bit (~precisione 7,2 min) |
| Identificatore locale | Nessuno | UID/GID POSIX a 32 bit |
| Dominio locale | Non presente | 0=UID, 1=GID, 2=Org |
| Campo node | Indirizzo MAC | Indirizzo MAC |
| Supporto libreria | Ampiamente supportato | Raramente supportato |
| Standard | RFC 4122 / RFC 9562 | Spec DCE (referenziata da RFC 4122) |
| Uso pratico | ID legacy ordinati per timestamp (Cassandra) | Solo contesti di sicurezza DCE |
UUID v2 non offre nulla rispetto a UUID v1 per uso generico, ed è strettamente peggiore nella maggior parte degli aspetti. Non c'è motivo di scegliere UUID v2 per il nuovo sviluppo.
Esempi di codice
UUID v2 non ha supporto nativo nelle librerie standard. I seguenti esempi mostrano come lavorare con i valori UUID v2:
Python — implementazione manuale
import uuid, struct, time
def uuid_v2(local_id: int, local_domain: int = 0) -> str:
"""
Generate a DCE Security UUID (v2).
local_domain: 0 = POSIX UID, 1 = POSIX GID, 2 = Org
local_id: 32-bit unsigned integer (e.g. os.getuid())
"""
# Get a v1 UUID for the time and node fields
v1 = uuid.uuid1()
fields = list(v1.fields) # [time_low, time_mid, time_hi_version, clock_seq_hi_variant, clock_seq_low, node]
# Replace time_low with local_id
fields[0] = local_id & 0xFFFFFFFF
# Replace version nibble: clear lower 12 bits of time_hi, set version 2
fields[2] = (fields[2] & 0x0FFF) | 0x2000
# Replace clock_seq_low with local_domain
fields[4] = local_domain & 0xFF
return str(uuid.UUID(fields=tuple(fields)))
import os
print(uuid_v2(os.getuid(), local_domain=0)) # POSIX UID
print(uuid_v2(os.getgid(), local_domain=1)) # POSIX GID
Go — nota
// The standard "github.com/google/uuid" package does NOT support v2. // You would need to implement it manually, similar to the Python example above. // Most Go developers use v4 or v7 for new projects. import "github.com/google/uuid" v4 := uuid.New() // v4 — recommended for most use cases v7, _ := uuid.NewV7() // v7 — time-ordered, ideal for database primary keys
JavaScript — estrarre i campi
Per estrarre il local_id e il dominio da una stringa UUID v2 esistente:
// Extracting fields from a UUID v2 string
const uuidStr = '000003e8-1234-2abc-8200-a1b2c3d4e5f6'
// ^^^^^^^^ ^^^^ ^ ^^
// local_id ver variant+clockSeqHi
// ^^ = local_domain (00 = POSIX UID)
const parts = uuidStr.split('-')
const localId = parseInt(parts[0], 16) // → 1000 (0x3e8)
const version = parseInt(parts[2][0], 16) // → 2
const localDomain = parseInt(parts[3].slice(2), 16) // low byte of octet pair
const DOMAIN_NAMES = ['POSIX UID', 'POSIX GID', 'Org']
console.log(`Local ID: ${localId}`) // Local ID: 1000
console.log(`Version: ${version}`) // Version: 2
console.log(`Domain: ${DOMAIN_NAMES[localDomain]}`) // Domain: POSIX UID
google/uuid supporta la generazione UUID v2 tramite uuid.NewDCEGroup() e uuid.NewDCEPerson() — una delle poche librerie mainstream che lo fa.