UUID v2 Generator
Generate DCE Security UUID v2 with local domain and ID
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
// 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 — 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á.