Co je UUID v2?
UUID v2 je verze UUID DCE Security, standardizovaná jako součást specifikace Distributed Computing Environment (DCE) a odkazovaná v RFC 4122. Rozšiřuje UUID v1 vložením identifikátoru uživatele nebo skupiny POSIX (UID/GID) do pole časového razítka.
Struktura je podobná UUID v1, ale 32bitové pole time_low je nahrazeno 32bitovým lokálním identifikátorem (např. POSIX UID) a 1bajtové pole local_domain identifikuje, jaký typ lokálního ID to je. Časové razítko je v důsledku toho zkráceno, čímž se snižuje jeho přesnost a záruky jedinečnosti.
UUID v2 je extrémně vzácné v moderním softwaru. Většina vývojářů ho nikdy nebude potřebovat generovat. Tato stránka dokumentuje formát pro úplnost a pro pomoc při dekódování hodnot UUID v2 nalezených ve starších systémech.
Struktura UUID v2
UUID v2 má stejný 128bitový formát s pomlčkami jako ostatní verze UUID. Pole se od UUID v1 liší takto:
| Pole | Bity | Účel |
|---|---|---|
| local_id | 32 | <code>local_id</code> — 32bitový identifikátor lokální domény (např. POSIX UID z <code>/etc/passwd</code>), nahrazuje pole time_low UUID v1 |
| time_mid | 16 | <code>time_mid</code> — střední 16 bitů zkráceného časového razítka UUID v1 |
| time_hi+version | 16 | <code>time_hi_and_version</code> — horních 12 bitů časového razítka s nibble verze nastaveným na <code>2</code> |
| variant+clock_hi | 8 | <code>clock_seq_hi_and_reserved</code> — variantní bity plus vysoká část sekvence hodin |
| local_domain | 8 | <code>local_domain</code> — identifikátor domény: <code>0</code> = Uživatel POSIX (UID), <code>1</code> = Skupina POSIX (GID), <code>2</code> = Organizace |
| node | 48 | <code>node</code> — 48bitová MAC adresa generujícího hostitele |
Příklad: 000003e8-92e0-21ef-8000-325096b39f47 — local_id 0x000003e8 = UID 1000, local_domain 0x00 = Uživatel POSIX
Hodnoty lokální domény
Bajt local_domain specifikuje typ lokálního identifikátoru vloženého do UUID:
Hodnoty domén jsou definovány specifikací DCE. Hodnoty 3–255 jsou rezervovány. V praxi se v reálných hodnotách UUID v2 běžně vyskytuje pouze doména 0 (Osoba/UID).
Proč se UUID v2 zřídka používá
Tři charakteristiky činí UUID v2 nepraktickým pro většinu moderních aplikací:
Hrubé rozlišení časového razítka
Časové razítko je zkráceno na 28 bitů (přibližně granularita 7,2 minuty). V tomto okně UUID generovaná se stejným local_id a doménou na stejném hostiteli nejsou jedinečná — specifikace se spoléhá na pole clock_seq pro jejich rozlišení, omezující jedinečnost na 64 hodnot na 7minutové okno.
Žádná podpora standardní knihovny
Na rozdíl od UUID v1 a v4 není UUID v2 podporováno většinou knihoven UUID. Balíček uuid npm, modul uuid Pythonu a java.util.UUID Javy v2 vynechávají. Je potřeba vlastní implementace.
POSIX-specifická sémantika
Koncept lokální domény (UID/GID) je ze své podstaty POSIX-specifický a nelze ho smysluplně přeložit do systémů Windows, vestavěných systémů nebo cloudových prostředí, kde koncept POSIX ID uživatele chybí.
Historický kontext
UUID v2 bylo definováno jako součást Distributed Computing Environment (DCE/RPC) Nadace Open Software na počátku 90. let. Cílem bylo vytvořit UUID, která mohla nést autorizační kontext — konkrétně umožnit RPC serveru identifikovat volajícího uživatele bez samostatného kroku autentizace.
Bezpečnostní model DCE předpokládal homogenní prostředí POSIX, kde každý uzel participoval ve sdíleném jmenném prostoru UID/GID. Vložené UID by umožnilo serveru rychle zkontrolovat seznamy řízení přístupu bez cesty tam a zpět do adresářové služby.
- Internet se přesunul od homogenních POSIX prostředí směrem k heterogenním cloudovým architekturám
- Moderní autentizace používá tokeny (JWT, OAuth) spíše než vložená UID v identifikátorech
- UUID v4 (plně náhodné) a UUID v7 (časově uspořádané) pokrývají praktické případy použití pro jedinečné identifikátory
- DCE/RPC samotné vypadlo ze širokého používání
RFC 4122 (2005) zahrnovalo UUID v2 odkazem na specifikaci DCE, ale záměrně vynechalo podrobný generovací algoritmus — s poznámkou, že byl definován DCE spíše než IETF.
RFC 9562 (2024), které aktualizovalo standard UUID, zachovalo UUID v2 pro historickou úplnost, ale nadále poznamenávalo jeho POSIX-specifickou povahu a absenci úplného generovacího algoritmu ve standardu IETF.
UUID v2 vs UUID v1
UUID v2 je odvozeno z UUID v1. Zde je jejich srovnání:
| Aspekt | UUID v1 | UUID v2 |
|---|---|---|
| Bity časového razítka | 60 bitů (~100ns přesnost) | 28 bitů (~přesnost 7,2 minuty) |
| Lokální identifikátor | Žádný | 32bitový POSIX UID/GID |
| Lokální doména | Není přítomna | 0=UID, 1=GID, 2=Org |
| Pole uzlu | MAC adresa | MAC adresa |
| Podpora knihovny | Široce podporováno | Zřídka podporováno |
| Standard | RFC 4122 / RFC 9562 | Specifikace DCE (odkazovaná RFC 4122) |
| Praktické použití | Starší časovým razítkem uspořádaná ID (Cassandra) | Pouze kontexty DCE Security |
UUID v2 nenabízí nic oproti UUID v1 pro obecné použití a je přísně horší ve většině ohledů. Neexistuje žádný důvod zvolit UUID v2 pro nový vývoj.
Příklady kódu
UUID v2 nemá nativní podporu ve standardních knihovnách. Následující příklady ukazují, jak pracovat s hodnotami UUID v2:
Python — ruční implementace
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 — poznámka
// "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 — extrahovat pole
Pro extrahování local_id a domény z existujícího řetězce UUID v2:
// 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 podporuje generování UUID v2 přes uuid.NewDCEGroup() a uuid.NewDCEPerson() — jedna z mála mainstream knihoven, která to dělá.