cv.cm

지식 · 텍스트, 데이터, 보안

UUID란 무엇인가요?

6분 분량

핵심 답변

UUID(universally unique identifier, 범용 고유 식별자)는 중앙 기관이 ID를 발급하지 않아도 데이터에 이름을 붙일 수 있게 해 주는 128비트 숫자입니다. f47ac10b-58cc-4372-a567-0e02b2c3d479처럼 16진수 32자리를 다섯 묶음으로 나눠 씁니다. 현재 표준인 RFC 9562는 여러 버전을 정의하는데, 버전 4는 완전히 무작위이고 버전 7은 타임스탬프로 시작해 생성 시각 순으로 정렬됩니다.

UUID 생성 열기

UUID 읽는 법

텍스트 형식은 36자로, 16진수 32자리와 하이픈 4개가 8-4-4-4-12로 묶여 있습니다. 바이너리로는 16바이트입니다. 모든 UUID에는 메타데이터를 담는 위치가 두 곳 있습니다.

  • 버전: 세 번째 묶음의 첫 자리입니다. f47ac10b-58cc-4372-a567-0e02b2c3d479에서는 4입니다.
  • 변형(variant): 네 번째 묶음의 첫 자리입니다. 표준 UUID에서는 8, 9, a, b 중 하나이며, 여기서는 a입니다.

같은 것을 Microsoft는 GUID라고 부르며 형식도 같습니다. 16진수의 대문자와 소문자는 동등하며, RFC 9562는 출력은 소문자로, 입력은 대소문자 구분 없이 받을 것을 권장합니다. 특수 값이 두 가지 있는데, 모두 0인 Nil UUID와 모두 f인 Max UUID입니다.

UUID 버전

2024년 5월에 발표된 RFC 9562는 RFC 4122를 대체하면서 버전 1~5를 유지하고 6, 7, 8을 추가했습니다.

버전구성 요소시간순 정렬주요 용도
1타임스탬프(1582년부터 100 ns 단위) + 클럭 시퀀스 + 노드 ID(주로 MAC 주소)텍스트로는 안 됨레거시 시스템
3네임스페이스와 이름의 MD5 해시아니요결정적 ID(v5 권장)
4무작위 122비트아니요범용 ID
5네임스페이스와 이름의 SHA-1 해시아니요같은 입력이면 항상 같은 UUID
6버전 1 필드를 상위 시간 비트부터 재배열예v1에서 이전
7밀리초 단위 48비트 유닉스 시간 + 무작위 비트예데이터베이스 키, 로그, 이벤트
8벤더가 정의하는 사용자 지정 구조구현에 따라 다름실험적 또는 애플리케이션 전용

버전 3과 5는 결정적입니다. DNS 이름용 네임스페이스와 example.com을 해시하면 어느 컴퓨터에서든 같은 UUID가 나옵니다. 여기서 MD5와 SHA-1은 보안용이 아니라 비트를 고르게 퍼뜨리는 수단으로만 쓰입니다.

버전 4 vs 버전 7

비트버전 4버전 7
0–47무작위밀리초 단위 유닉스 타임스탬프
48–51버전 0100 (4)버전 0111 (7)
52–63무작위무작위 또는 밀리초 미만 카운터
64–65변형 10변형 10
66–127무작위무작위
무작위 비트 수122최대 74

RFC에 실린 버전 7 예시는 017f22e2-79b0-7cc3-98c4-dc0c0c07398f입니다. 앞 12자리 16진수 017f22e279b0은 유닉스 에포크로부터 1,645,557,742,000밀리초, 즉 2022-02-22 19:22:22 UTC입니다.

실질적인 차이는 데이터베이스 성능입니다. 무작위인 v4 키는 B-트리 인덱스의 아무 위치에나 들어가 페이지를 분할시키고 쓰기를 인덱스 전체로 흩어 놓습니다. 시간순인 v7 키는 자동 증가 정수처럼 끝부분에 추가되므로 삽입이 빠르고 인덱스가 촘촘하게 유지됩니다. 새 데이터베이스의 기본 키로는 보통 v7이 낫고, 생성 시각이 드러나면 안 되는 불투명 토큰에는 v4를 쓰세요.

얼마나 고유할까?

무작위 비트가 122개이므로 가능한 버전 4 UUID는 약 5.3 × 10^36개입니다. 생일 문제 한계에 따르면 충돌이 한 번이라도 일어날 확률이 50%에 이르려면 약 2.7 × 10^18개가 필요합니다. 초당 10억 개씩 생성해도 약 86년이 걸립니다.

실제 충돌은 수학이 아니라 나쁜 난수에서 생깁니다. 같은 난수 상태로 복제된 가상 머신이나 Math.random() 같은 비암호학적 함수로 만든 생성기는 같은 값을 반복할 수 있습니다. 브라우저와 Node.js의 crypto.randomUUID(), Python의 uuid.uuid4(), PostgreSQL의 gen_random_uuid()처럼 암호학적으로 안전한 소스를 쓰세요.

UUID 저장하기

  • PostgreSQL의 uuid처럼 네이티브 타입이 있으면 쓰세요. 텍스트의 36바이트 대신 16바이트를 차지합니다.
  • MySQL에서는 BINARY(16)으로 저장하세요. 텍스트로 저장하면 인덱스 크기가 두 배 이상 커집니다.
  • UUID는 대소문자를 구분하지 않고 비교하거나, 입력 시 소문자로 정규화하세요.
  • v4 UUID에서 의미를 뽑아내려 하지 마세요. 정보를 담은 것은 버전 비트와 변형 비트뿐입니다.

자주 묻는 질문

UUID와 GUID는 무엇이 다른가요?

실질적으로 차이가 없습니다. GUID는 Microsoft가 쓰는 이름이며, UUID와 같은 128비트 형식과 버전을 따릅니다.

두 UUID가 같아질 수도 있나요?

이론상으로는 가능하지만, 안전한 난수 소스로 생성하면 실제로는 일어나지 않습니다. 버전 4 UUID가 100경 개를 훨씬 넘게 존재할 때까지 충돌 확률은 무시할 만한 수준입니다.

어떤 UUID 버전을 써야 하나요?

데이터베이스 키나 시간순 정렬이 유리한 곳에는 버전 7, ID가 아무 정보도 드러내면 안 될 때는 버전 4, 같은 입력에서 항상 같은 ID가 나와야 할 때는 버전 5를 쓰세요.

JavaScript에서 UUID를 생성하려면 어떻게 하나요?

crypto.randomUUID()를 호출하세요. 암호학적으로 안전한 생성기로 버전 4 UUID를 반환합니다. 최신 브라우저의 HTTPS 페이지와 Node.js 19 이상에서 전역 함수로 동작합니다.

전체 지식 문서