UUID v2 생성기
Generate DCE Security UUID v2 with local domain and ID
UUID v2란 무엇인가요?
UUID v2는 DCE 보안 UUID 버전으로, 분산 컴퓨팅 환경(DCE) 사양의 일부로 표준화되고 RFC 4122에서 참조됩니다. POSIX 사용자 또는 그룹 식별자(UID/GID)를 타임스탬프 필드에 내장하여 UUID v1을 확장합니다.
구조는 UUID v1과 유사하지만 32비트 time_low 필드가 32비트 로컬 식별자(예: POSIX UID)로 대체되고 1바이트 local_domain 필드가 어떤 종류의 로컬 ID인지 식별합니다.
UUID v2는 현대 소프트웨어에서 매우 드뭅니다. 대부분의 개발자는 절대 생성할 필요가 없습니다. 이 페이지는 완전성을 위해 형식을 문서화하고 레거시 시스템에서 발견된 UUID v2 값 디코딩을 돕습니다.
UUID v2 구조
UUID v2는 다른 UUID 버전과 동일한 128비트 하이픈 형식을 가집니다. 필드는 UUID v1과 다음과 같이 다릅니다:
| 필드 | 비트 | 목적 |
|---|---|---|
| local_id | 32 | <code>local_id</code>——32비트 로컬 도메인 식별자(예: <code>/etc/passwd</code>의 POSIX UID), UUID v1의 time_low 필드 대체 |
| time_mid | 16 | <code>time_mid</code>——잘린 UUID v1 타임스탬프의 중간 16비트 |
| time_hi+version | 16 | <code>time_hi_and_version</code>——버전 니블을 <code>2</code>로 설정한 상위 12 타임스탬프 비트 |
| variant+clock_hi | 8 | <code>clock_seq_hi_and_reserved</code>——변형 비트와 클럭 시퀀스의 상위 부분 |
| local_domain | 8 | <code>local_domain</code>——도메인 식별자: <code>0</code> = POSIX 사용자(UID), <code>1</code> = POSIX 그룹(GID), <code>2</code> = 조직 |
| node | 48 | <code>node</code>——생성 호스트의 48비트 MAC 주소 |
예: 000003e8-92e0-21ef-8000-325096b39f47——local_id 0x000003e8 = UID 1000, local_domain 0x00 = POSIX 사용자
로컬 도메인 값
local_domain 바이트는 UUID에 내장된 로컬 식별자의 유형을 지정합니다:
도메인 값은 DCE 사양으로 정의됩니다. 값 3-255는 예약됩니다. 실제로는 도메인 0(Person/UID)만 실제 UUID v2 값에서 일반적으로 볼 수 있습니다.
UUID v2가 거의 사용되지 않는 이유
세 가지 특성이 UUID v2를 대부분의 현대 애플리케이션에서 비실용적으로 만듭니다:
거친 타임스탬프 해상도
타임스탬프는 28비트로 잘려집니다(약 7.2분 단위). 해당 윈도우 내에서 동일한 호스트의 같은 local_id와 도메인으로 생성된 UUID는 고유하지 않습니다.
표준 라이브러리 지원 없음
UUID v1과 v4와 달리 UUID v2는 대부분의 UUID 라이브러리에서 지원되지 않습니다. uuid npm 패키지, Python의 uuid 모듈, Java의 java.util.UUID 모두 v2를 생략합니다. 사용자 정의 구현이 필요합니다.
POSIX 특정 의미론
로컬 도메인 개념(UID/GID)은 본질적으로 POSIX 특정이며 POSIX 사용자 ID 개념이 없는 Windows, 임베디드 시스템 또는 클라우드 환경에서는 의미가 없습니다.
역사적 배경
UUID v2는 1990년대 초 Open Software Foundation의 분산 컴퓨팅 환경(DCE/RPC)의 일부로 정의되었습니다. 목표는 권한 부여 컨텍스트를 전달할 수 있는 UUID를 만드는 것이었습니다.
DCE 보안 모델은 모든 노드가 공유 UID/GID 네임스페이스에 참여하는 동질적인 POSIX 환경을 가정했습니다.
- 인터넷이 동질적인 POSIX 환경에서 이기종 클라우드 아키텍처로 이동
- 현대 인증은 식별자에 내장된 UID 대신 토큰(JWT, OAuth) 사용
- UUID v4(완전히 무작위)와 UUID v7(시간 순서)이 고유 식별자의 실제 사용 사례 커버
- DCE/RPC 자체도 광범위한 사용에서 벗어남
RFC 4122(2005)는 DCE 사양 참조로 UUID v2를 포함했지만 상세한 생성 알고리즘을 의도적으로 생략했습니다.
RFC 9562(2024)는 UUID 표준을 업데이트하며 역사적 완전성을 위해 UUID v2를 유지했지만 계속해서 POSIX 특정 특성을 지적했습니다.
UUID v2 대 UUID v1
UUID v2는 UUID v1에서 파생되었습니다. 비교:
| 측면 | UUID v1 | UUID v2 |
|---|---|---|
| 타임스탬프 비트 | 60비트(~100ns 정밀도) | 28비트(~7.2분 정밀도) |
| 로컬 식별자 | 없음 | 32비트 POSIX UID/GID |
| 로컬 도메인 | 없음 | 0=UID, 1=GID, 2=조직 |
| 노드 필드 | MAC 주소 | MAC 주소 |
| 라이브러리 지원 | 광범위하게 지원 | 거의 지원 없음 |
| 표준 | RFC 4122 / RFC 9562 | DCE 사양(RFC 4122에서 참조) |
| 실제 사용 | 레거시 타임스탬프 순서 ID(Cassandra) | DCE 보안 컨텍스트 전용 |
UUID v2는 범용 사용에서 UUID v1보다 유리한 점이 없으며 대부분의 측면에서 엄격히 더 나쁩니다. 새 개발에서 UUID v2를 선택할 이유가 없습니다.
코드 예제
UUID v2는 표준 라이브러리에서 네이티브 지원이 없습니다. 다음 예제는 UUID v2 값을 다루는 방법을 보여줍니다:
Python——수동 구현
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——필드 추출
기존 UUID v2 문자열에서 local_id와 도메인을 추출하려면:
// 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.NewDCEGroup()과 uuid.NewDCEPerson()을 통해 UUID v2 생성을 지원합니다——이를 지원하는 몇 안 되는 주류 라이브러리 중 하나입니다.