เครื่องสร้าง UUID v2
สร้าง UUID v2 DCE Security พร้อม local domain และ ID
UUID v2 คืออะไร?
UUID v2 คือ UUID version DCE Security กำหนดมาตรฐานเป็นส่วนหนึ่งของ Distributed Computing Environment (DCE) specification และอ้างอิงใน RFC 4122 ขยาย UUID v1 โดยฝัง POSIX user หรือ group identifier (UID/GID) ลงใน timestamp field
โครงสร้างคล้าย UUID v1 แต่ฟิลด์ time_low 32 บิตถูกแทนที่ด้วย local identifier 32 บิต (เช่น POSIX UID) และฟิลด์ local_domain 1 byte ระบุประเภทของ local ID timestamp ถูกตัดทอนส่งผลให้ความแม่นยำและการรับประกัน uniqueness ลดลง
UUID v2 หายากมาก ในซอฟต์แวร์สมัยใหม่ นักพัฒนาส่วนใหญ่ไม่เคยต้องสร้างมัน หน้านี้ document format เพื่อความสมบูรณ์และช่วยในการถอดรหัสค่า UUID v2 ที่พบในระบบ legacy
โครงสร้าง UUID v2
UUID v2 มีรูปแบบ 128 บิต พร้อมขีดกลางเหมือน UUID version อื่น ฟิลด์แตกต่างจาก UUID v1 ดังนี้:
| Field | Bits | วัตถุประสงค์ |
|---|---|---|
| local_id | 32 | <code>local_id</code> — local domain identifier 32 บิต (เช่น POSIX UID จาก <code>/etc/passwd</code>) แทนที่ time_low field ของ UUID v1 |
| time_mid | 16 | <code>time_mid</code> — 16 บิตกลางของ UUID v1 timestamp ที่ถูกตัดทอน |
| time_hi+version | 16 | <code>time_hi_and_version</code> — 12 บิต timestamp บนสุดพร้อม version nibble ตั้งเป็น <code>2</code> |
| variant+clock_hi | 8 | <code>clock_seq_hi_and_reserved</code> — variant bit บวกส่วนสูงของ clock sequence |
| local_domain | 8 | <code>local_domain</code> — domain identifier: <code>0</code> = POSIX User (UID), <code>1</code> = POSIX Group (GID), <code>2</code> = Organization |
| node | 48 | <code>node</code> — MAC address 48 บิตของ host ที่สร้าง |
ตัวอย่าง: 000003e8-92e0-21ef-8000-325096b39f47 — local_id 0x000003e8 = UID 1000, local_domain 0x00 = POSIX User
ค่า Local Domain
byte local_domain ระบุประเภทของ local identifier ที่ฝังใน UUID:
ค่า domain กำหนดโดย DCE specification ค่า 3–255 สงวนไว้ ในทางปฏิบัติ เฉพาะ domain 0 (Person/UID) ที่พบในค่า UUID v2 จริงทั่วไป
ทำไม UUID v2 ถึงไม่ค่อยถูกใช้
สามลักษณะทำให้ UUID v2 ไม่เหมาะสมสำหรับแอปพลิเคชันสมัยใหม่ส่วนใหญ่:
Timestamp Resolution หยาบ
timestamp ถูกตัดทอนเหลือ 28 บิต (ความละเอียดประมาณ 7.2 นาที) ในช่วงนั้น UUID ที่สร้างด้วย local_id และ domain เดิมบน host เดิมไม่มีความไม่ซ้ำกัน spec อาศัยฟิลด์ clock_seq เพื่อแยกพวกมัน จำกัดความไม่ซ้ำกันที่ 64 ค่าต่อหน้าต่าง 7 นาที
ไม่มี Standard Library Support
ต่างจาก UUID v1 และ v4 UUID v2 ไม่รองรับโดย UUID library ส่วนใหญ่ npm package uuid, module uuid ของ Python, และ java.util.UUID ของ Java ล้วนละเว้น v2 ต้องการการ implement แบบกำหนดเอง
Semantics เฉพาะ POSIX
แนวคิด local domain (UID/GID) เป็น POSIX-specific โดยเนื้อแท้และไม่มีความหมายที่แปลได้ไปยัง Windows, ระบบ embedded หรือ cloud environment ที่แนวคิด POSIX user ID ไม่มีอยู่
บริบทเชิงประวัติศาสตร์
UUID v2 กำหนดเป็นส่วนหนึ่งของ Distributed Computing Environment (DCE/RPC) ของ Open Software Foundation ในต้นทศวรรษ 1990 เป้าหมายคือสร้าง UUID ที่สามารถพา authorization context ได้ โดยเฉพาะให้ RPC server ระบุ user ที่เรียกโดยไม่ต้องมีขั้นตอน authentication แยก
security model ของ DCE สมมติ สภาพแวดล้อม POSIX แบบ homogeneous ที่ทุก node ร่วมใน UID/GID namespace ที่ใช้ร่วมกัน UID ที่ฝังจะช่วยให้ server ตรวจสอบ access control list อย่างรวดเร็วโดยไม่ต้องไปกลับไปยัง directory service
- อินเทอร์เน็ตย้ายออกจากสภาพแวดล้อม POSIX แบบ homogeneous ไปยัง cloud architecture แบบ heterogeneous
- การ authentication สมัยใหม่ใช้ token (JWT, OAuth) แทนการฝัง UID ใน identifier
- UUID v4 (สุ่มทั้งหมด) และ UUID v7 (เรียงตามเวลา) ครอบคลุมกรณีการใช้งานจริงสำหรับ unique identifier
- DCE/RPC เองก็ออกไปจากการใช้งานแพร่หลาย
RFC 4122 (2005) รวม UUID v2 โดยอ้างอิง DCE specification แต่ละเว้น generation algorithm โดยตั้งใจ โดยระบุว่ากำหนดโดย DCE ไม่ใช่ IETF
RFC 9562 (2024) ซึ่งอัปเดต UUID standard เก็บ UUID v2 ไว้เพื่อความสมบูรณ์เชิงประวัติศาสตร์ แต่ยังคงระบุถึงลักษณะ POSIX-specific และการขาด generation algorithm ที่สมบูรณ์ในมาตรฐาน IETF
UUID v2 vs UUID v1
UUID v2 มาจาก UUID v1 ต่อไปนี้คือการเปรียบเทียบ:
| ด้าน | UUID v1 | UUID v2 |
|---|---|---|
| Timestamp bit | 60 บิต (~ความแม่นยำ 100ns) | 28 บิต (~ความแม่นยำ 7.2 นาที) |
| Local identifier | ไม่มี | POSIX UID/GID 32 บิต |
| Local domain | ไม่มี | 0=UID, 1=GID, 2=Org |
| Node field | MAC address | MAC address |
| Library support | รองรับกว้างขวาง | ไม่ค่อยรองรับ |
| มาตรฐาน | RFC 4122 / RFC 9562 | DCE spec (อ้างอิงโดย RFC 4122) |
| การใช้งานจริง | Legacy timestamp-ordered ID (Cassandra) | เฉพาะ DCE Security context |
UUID v2 ไม่มีอะไรเหนือกว่า UUID v1 สำหรับการใช้งานทั่วไป และแย่กว่าในแง่มุมส่วนใหญ่ ไม่มีเหตุผลที่จะเลือก UUID v2 สำหรับการพัฒนาใหม่
ตัวอย่างโค้ด
UUID v2 ไม่มี native support ใน standard library ตัวอย่างต่อไปนี้แสดงวิธีทำงานกับค่า UUID v2:
Python — การ implement แบบ manual
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 — หมายเหตุ
// 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 — ดึงฟิลด์
การดึง local_id และ domain จาก UUID v2 string ที่มีอยู่:
// 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 ของ Go รองรับการสร้าง UUID v2 ผ่าน uuid.NewDCEGroup() และ uuid.NewDCEPerson() ซึ่งเป็นหนึ่งใน library กระแสหลักไม่กี่ตัวที่ทำเช่นนั้น