Wat is UUID v2?
UUID v2 is de DCE Security-UUID-versie, gestandaardiseerd als onderdeel van de Distributed Computing Environment (DCE)-specificatie en aangeduid in RFC 4122. Het breidt UUID v1 uit door een POSIX-gebruikers- of groepsidentificator (UID/GID) in het tijdstempelveld in te bedden.
De structuur lijkt op UUID v1, maar het 32-bit time_low-veld wordt vervangen door een 32-bit lokale identificator (bijv. een POSIX UID) en een 1-byte local_domain-veld geeft aan wat voor soort lokale ID het is. Het tijdstempel wordt hierdoor afgekapt, wat de precisie en uniciteitsgaranties vermindert.
UUID v2 is uiterst zeldzaam in moderne software. De meeste ontwikkelaars hoeven er nooit een te genereren. Deze pagina documenteert het formaat voor de volledigheid en om te helpen bij het decoderen van UUID v2-waarden die in legacy-systemen worden aangetroffen.
UUID v2-structuur
Een UUID v2 heeft hetzelfde 128-bit, afgestreepte formaat als andere UUID-versies. De velden wijken als volgt af van UUID v1:
| Veld | Bits | Doel |
|---|---|---|
| local_id | 32 | <code>local_id</code> — 32-bit lokale domeinidentificator (bijv. POSIX UID uit <code>/etc/passwd</code>), vervangt het time_low-veld van UUID v1 |
| time_mid | 16 | <code>time_mid</code> — middelste 16 bits van het afgekapte UUID v1-tijdstempel |
| time_hi+version | 16 | <code>time_hi_and_version</code> — bovenste 12 tijdstempelbits met versienibble ingesteld op <code>2</code> |
| variant+clock_hi | 8 | <code>clock_seq_hi_and_reserved</code> — variantbits plus het hoge gedeelte van de kloksequentie |
| local_domain | 8 | <code>local_domain</code> — domeinidentificator: <code>0</code> = POSIX User (UID), <code>1</code> = POSIX Group (GID), <code>2</code> = Organisatie |
| node | 48 | <code>node</code> — 48-bit MAC-adres van de genererende host |
Voorbeeld: 000003e8-92e0-21ef-8000-325096b39f47 — local_id 0x000003e8 = UID 1000, local_domain 0x00 = POSIX User
Lokale domeinwaarden
De local_domain-byte geeft het type lokale identificator aan dat in de UUID is ingebed:
De domeinwaarden zijn gedefinieerd door de DCE-specificatie. Waarden 3–255 zijn gereserveerd. In de praktijk wordt alleen domein 0 (Person/UID) regelmatig aangetroffen in UUID v2-waarden uit de echte wereld.
Waarom UUID v2 zelden wordt gebruikt
Drie eigenschappen maken UUID v2 onpraktisch voor de meeste moderne toepassingen:
Grove tijdstempelresolutie
Het tijdstempel wordt afgekapt tot 28 bits (ongeveer 7,2 minuten granulariteit). Binnen dat venster zijn UUIDs die met dezelfde local_id en hetzelfde domein op dezelfde host zijn gegenereerd niet uniek — de specificatie vertrouwt op het clock_seq-veld om ze te onderscheiden, waardoor de uniciteit beperkt is tot 64 waarden per 7-minutenvenster.
Geen ondersteuning in standaardbibliotheken
In tegenstelling tot UUID v1 en v4 wordt UUID v2 niet ondersteund door de meeste UUID-bibliotheken. Het npm-pakket uuid, Python's uuid-module en Java's java.util.UUID laten v2 allemaal weg. Een eigen implementatie is vereist.
POSIX-specifieke semantiek
Het lokale domein-concept (UID/GID) is van nature POSIX-specifiek en vertaalt zich niet zinvol naar Windows, embedded systemen of cloudomgevingen waar het concept van een POSIX-gebruikers-ID ontbreekt.
Historische context
UUID v2 werd gedefinieerd als onderdeel van de Open Software Foundation's Distributed Computing Environment (DCE/RPC) in het begin van de jaren negentig. Het doel was om UUIDs te maken die autorisatiecontext konden bevatten — met name om een RPC-server in staat te stellen de aanroepende gebruiker te identificeren zonder een aparte authenticatiestap.
Het DCE-beveiligingsmodel veronderstelde een homogene POSIX-omgeving waarbij elk knooppunt deelnam aan een gedeelde UID/GID-naamruimte. De ingebedde UID zou de server in staat stellen toegangscontrolelijsten snel te controleren zonder een round-trip naar een directoryservice.
- Het internet verwijderde zich van homogene POSIX-omgevingen naar heterogene cloudarchitecturen
- Moderne authenticatie gebruikt tokens (JWT, OAuth) in plaats van ingebedde UIDs in identificatoren
- UUID v4 (volledig willekeurig) en UUID v7 (tijdgeordend) dekken de praktische gebruiksscenario's voor unieke identificatoren
- DCE/RPC zelf raakte buiten wijdverspreid gebruik
RFC 4122 (2005) verwees naar UUID v2 via de DCE-specificatie, maar liet het gedetailleerde generatie-algoritme bewust weg — met de opmerking dat dit door DCE was gedefinieerd en niet door de IETF.
RFC 9562 (2024), dat de UUID-standaard bijwerkte, behield UUID v2 voor historische volledigheid maar bleef de POSIX-specifieke aard ervan en het ontbreken van een volledig generatie-algoritme in de IETF-standaard vermelden.
UUID v2 vs UUID v1
UUID v2 is afgeleid van UUID v1. Hier is een vergelijking:
| Aspect | UUID v1 | UUID v2 |
|---|---|---|
| Tijdstempelbits | 60 bits (~100 ns precisie) | 28 bits (~7,2 minuten precisie) |
| Lokale identificator | Geen | 32-bit POSIX UID/GID |
| Lokaal domein | Niet aanwezig | 0=UID, 1=GID, 2=Org |
| Node-veld | MAC-adres | MAC-adres |
| Bibliotheekundersteuning | Breed ondersteund | Zelden ondersteund |
| Standaard | RFC 4122 / RFC 9562 | DCE-spec (aangeduid in RFC 4122) |
| Praktisch gebruik | Legacy tijdgeordende IDs (Cassandra) | Uitsluitend DCE Security-contexten |
UUID v2 biedt niets extra's ten opzichte van UUID v1 voor algemeen gebruik, en is in de meeste opzichten aantoonbaar slechter. Er is geen reden om UUID v2 te kiezen voor nieuwe ontwikkeling.
Codevoorbeelden
UUID v2 heeft geen native ondersteuning in standaardbibliotheken. De volgende voorbeelden laten zien hoe u met UUID v2-waarden kunt werken:
Python — handmatige implementatie
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 — google/uuid
// "github.com/google/uuid" supports DCE (v2) via two helper functions: import "github.com/google/uuid" v2Person := uuid.NewDCEPerson() // v2, local_domain=0, local_id=os.Getuid() v2Group := uuid.NewDCEGroup() // v2, local_domain=1, local_id=os.Getgid() // For most new projects, prefer: v4 := uuid.New() // v4 — random, universally supported v7, _ := uuid.NewV7() // v7 — time-ordered, good for database primary keys
JavaScript — velden extraheren
Om de local_id en het domein uit een bestaande UUID v2-string te extraheren:
// 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 is een van de weinige gangbare bibliotheken met native UUID v2-ondersteuning. De meeste andere (npm uuid, Python's uuid-module, Java's java.util.UUID) laten het volledig weg.