UUID v3 생성기
Generate deterministic name-based UUID v3 using MD5
네임스페이스
6ba7b810-9dad-11d1-80b4-00c04fd430c8
이름
생성된 UUID v3
UUID v3이란 무엇인가요?
UUID v3은 RFC 4122에 정의된 이름 기반 UUID 버전입니다. 무작위 데이터나 타임스탬프 대신 네임스페이스 UUID와 이름 문자열 두 입력에서 UUID를 결정론적으로 파생합니다. 네임스페이스 + 이름 쌍은 MD5로 해시되고 결과 해시가 UUID로 포맷됩니다.
UUID v3의 핵심 속성은 결정론입니다: 동일한 네임스페이스와 이름은 어느 머신에서나 언제나 동일한 UUID를 생성합니다. 이로 인해 의미 있는 이름으로 식별되는 리소스의 안정적 식별자를 생성하는 콘텐츠 주소 지정에 적합합니다.
UUID v3은 해시 함수로 MD5를 사용합니다. MD5는 보안 목적으로 암호학적으로 손상된 것으로 간주되며 이것이 UUID v5(SHA-1 사용)가 새 개발에 일반적으로 선호되는 이유입니다.
표준 네임스페이스
RFC 4122는 4개의 사전 할당된 네임스페이스 UUID를 정의합니다. 표준 네임스페이스를 사용하면 상호 운용성이 보장됩니다——두 독립 구현이 동일한 네임스페이스 내의 동일한 이름에 대해 동일한 UUID v3을 생성합니다:
| 네임스페이스 | UUID | 사용 대상 |
|---|---|---|
| DNS | 6ba7b810-9dad-11d1-80b4-00c04fd430c8 | 완전히 정규화된 도메인 이름(예: 'example.com') |
| URL | 6ba7b811-9dad-11d1-80b4-00c04fd430c8 | URL 및 URI(예: 'https://example.com/resource') |
| OID | 6ba7b812-9dad-11d1-80b4-00c04fd430c8 | ISO 개체 식별자(예: '1.2.840.113556') |
| X.500 | 6ba7b814-9dad-11d1-80b4-00c04fd430c8 | X.500 고유 이름(예: 'cn=John,dc=example,dc=com') |
임의의 UUID를 맞춤 네임스페이스로 사용할 수도 있습니다——예를 들어 한 번 생성하여 애플리케이션에 상수로 내장한 UUID v4. 이를 통해 자체 이름-UUID 매핑을 위한 개인 네임스페이스를 만들 수 있습니다.
UUID v3 대 UUID v5
UUID v3과 UUID v5는 구조적으로 동일합니다——둘 다 결정론적 이름 기반 UUID입니다. 유일한 차이점은 해시 함수입니다:
- MD5 해싱 사용
- 128비트 출력(UUID 크기)
- RFC 4122에 정의
- MD5는 암호학적으로 손상됨
- 모든 UUID 라이브러리에서 지원
- SHA-1 해싱 사용
- 160비트 해시를 128비트로 자름
- RFC 4122에 정의
- SHA-1은 보안용으로 더 이상 사용되지 않지만 MD5보다 강함
- 모든 UUID 라이브러리에서 지원
모든 새 개발에서 UUID v3보다 UUID v5를 선호하세요. SHA-1 해시가 MD5보다 강하고 성능 차이는 무시할 수 있습니다. 이미 사용 중인 시스템에서 UUID를 재현해야 할 때만 UUID v3을 사용하세요.
UUID v3을 사용할 때
UUID v3(및 v5)은 저장하고 조회해야 하는 무작위 ID 대신 의미 있는 이름에서 파생된 안정적이고 재현 가능한 식별자가 필요할 때 적합합니다:
결정론 이해
UUID v3의 결정론은 가장 큰 강점이자 가장 중요한 제약입니다. 어떤 네임스페이스 UUID와 어떤 이름 문자열이 주어지더라도 출력 UUID는 완전히 고정됩니다——무작위성이 관여하지 않습니다. 즉:
항상 생성: 9073926b-929f-31c2-abc9-fad77ae3e8eb
공격자가 네임스페이스를 알고 이름을 추측할 수 있다면 UUID를 미리 계산할 수 있습니다. UUID v3 값은 예측 불가능한 토큰, 세션 ID, 또는 비밀로 절대 사용하지 마세요. 보안에 민감한 식별자에는 UUID v4를 사용하세요.
코드 예제
UUID v3에는 네임스페이스 UUID와 이름 문자열이 필요합니다. 표준 uuid 패키지를 사용하세요:
// Browser / Node.js — UUID v3 without dependencies
function uuidV3(namespace, name) {
// namespace must be a UUID string like '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
const nsBytes = namespace.replace(/-/g, '').match(/../g).map(h => parseInt(h, 16))
const nameBytes = [...new TextEncoder().encode(name)]
const combined = new Uint8Array([...nsBytes, ...nameBytes])
// md5(combined) — use your preferred MD5 library or the inline implementation
const hash = md5(combined) // returns Uint8Array(16)
hash[6] = (hash[6] & 0x0f) | 0x30 // version 3
hash[8] = (hash[8] & 0x3f) | 0x80 // variant
const h = [...hash].map(b => b.toString(16).padStart(2, '0')).join('')
return `${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20)}`
}
// Using the 'uuid' npm package
import { v3 as uuidv3 } from 'uuid'
const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
console.log(uuidv3('example.com', uuidv3.DNS))
// → '9073926b-929f-31c2-abc9-fad77ae3e8eb' (always the same)import uuid
# Using the standard library
dns_uuid = uuid.uuid3(uuid.NAMESPACE_DNS, 'example.com')
print(dns_uuid)
# → 9073926b-929f-31c2-abc9-fad77ae3e8eb
url_uuid = uuid.uuid3(uuid.NAMESPACE_URL, 'https://example.com/page')
print(url_uuid)
# Custom namespace
MY_NS = uuid.UUID('a1b2c3d4-e5f6-7890-abcd-ef1234567890')
custom = uuid.uuid3(MY_NS, 'my-entity-name')
print(custom)package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
// Standard DNS namespace
ns := uuid.MustParse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
id := uuid.NewMD5(ns, []byte("example.com"))
fmt.Println(id)
// → 9073926b-929f-31c2-abc9-fad77ae3e8eb
// URL namespace
urlNS := uuid.MustParse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
idURL := uuid.NewMD5(urlNS, []byte("https://example.com/page"))
fmt.Println(idURL)
}