UUID v4 생성기
브라우저에서 UUID v4를 안전하게 생성. 테스트 데이터와 DB 기본 키 확인에 적합. 1~100개 일괄 생성 지원.
복사되었습니다
📖 자주 걸리는 지점
crypto.randomUUID()(Web Crypto API)를 사용해 UUID v4 를 1~100 개 생성합니다. 하이픈의 유무를 바꿀 수 있고 처리는 브라우저 안에서 끝납니다. UUID 의 설계상의 목적은 조정 없이 유일한 식별자를 만들 수 있다는 것뿐이며 순서도 의미도 짧음도 갖지 않습니다 — 이 세 가지가 없다는 것이 데이터베이스나 URL 에서 쓸 때의 문제를 거의 전부 낳습니다.
| 사례 | 무슨 일이 일어나는가 | 어떻게 하면 되는가 |
|---|---|---|
| 기본 키로 쓰면 데이터베이스가 느려진다 | UUID v4 는 완전히 랜덤이므로 삽입되는 위치가 인덱스 안에서 흩어집니다. B-tree 는 끝에 덧붙이는 것이 가장 효율적인 구조이므로 랜덤한 삽입은 페이지 분할을 빈발시키고 인덱스가 단편화됩니다. MySQL 의 InnoDB 는 기본 키가 클러스터드 인덱스 — 즉 행의 데이터 자체가 기본 키 순으로 늘어서 있습니다 — 이므로 영향은 더욱 커서 수천만 행의 규모가 되면 연번 기본 키에 비해 삽입이 몇 배 느려지고 인덱스의 크기도 부풉니다. 더해서 CHAR(36) 으로 저장하면 연번 BIGINT(8 바이트)의 4.5 배의 용량을 모든 외래 키와 인덱스에서 소비합니다. |
시각순으로 늘어서는 UUID v7 을 쓰세요 — 앞 48 비트가 Unix 밀리초이므로 생성 순으로 정렬되고 B-tree 로의 삽입이 끝에 집중됩니다. UUID 의 겉모습과 유일성은 그대로이며 이 문제만을 해결하기 위해 설계된 버전입니다(RFC 9562 로 표준화되었습니다). v7 을 쓸 수 없는 환경이라면 내부의 기본 키는 연번으로 하고 외부에 보여 줄 ID 만 UUID 를 별도 열로 갖는 것이 확실합니다. 저장 형식도 재검토하세요 — CHAR(36) 이 아니라 BINARY(16) 으로 하면 용량은 절반 이하가 됩니다(PostgreSQL 에는 uuid 타입이 있습니다). 먼저 정말로 UUID 가 필요한지를 확인하세요 — 분산 생성도 오프라인 생성도 필요 없다면 연번으로 충분합니다. |
| UUID 를 비밀 값으로 써 버린다 | UUID v4 의 랜덤 부분은 122 비트이므로 추측은 현실적으로 불가능합니다 — 이 점만을 보고 URL 에 UUID 를 넣어 두면 아는 사람만 접근할 수 있다는 설계가 채택되는 경우가 있습니다. 그러나 UUID 는 식별자이지 비밀로 다루는 전제의 값이 아닙니다 — URL 에 넣으면 브라우저의 기록 · 리퍼러 헤더 · 액세스 로그 · 프록시의 로그 · 공유된 링크에 남습니다. 나아가 UUID v1 은 MAC 주소와 생성 시각을 포함하고 있으므로 애초에 랜덤하지조차 않습니다 — v1 을 세션 ID 나 비밀번호 재설정 토큰에 쓰는 것은 위험합니다. | 알고 있으면 접근할 수 있다는 설계 자체를 피하세요 — 접근 제어는 인증과 인가로 하는 것이 정석이며 URL 의 추측 곤란함에 기대는 것은 보조에 지나지 않습니다. 공유 링크처럼 URL 자체를 열쇠로 삼는 설계가 필요한 경우에는 UUID 가 아니라 전용 토큰을 쓰고 유효 기간과 실효의 구조를 붙이세요 — crypto.getRandomValues() 로 32 바이트의 난수를 생성해 Base64url 로 하는 것이 표준적입니다. 그리고 그 URL 이 로그에 남지 않도록 경로가 아니라 프래그먼트(# 이후)에 두거나 POST 로 보내세요 — 프래그먼트는 서버에 전송되지 않습니다. UUID 는 이것이 무엇인가를 나타내는 것이지 당신이 누구인가를 증명하는 것이 아닙니다. |
| 표기의 흔들림으로 같은 ID 가 다른 것으로 다뤄진다 | UUID 에는 표기의 선택지가 여럿 있습니다 — 대문자와 소문자(A1B2 와 a1b2), 하이픈의 유무(36 자와 32 자), 그리고 중괄호로 감싸는 형식({...}, Microsoft 의 관습)입니다. RFC 4122 는 생성 시는 소문자, 수용은 대소 양쪽 이라고 정하고 있습니다만 문자열로 비교하면 이들은 전부 다른 것이 됩니다. 실무에서는 어떤 시스템이 대문자로 반환하고 다른 시스템이 소문자로 저장하고 있으면 같은 레코드가 중복해 만들어집니다 — 게다가 데이터베이스의 조합 순서에 따라서는 일치하기도 하고 안 하기도 하므로 환경마다 동작이 달라져 원인을 잡을 수 없게 됩니다. |
시스템의 입구에서 하나의 형식으로 정규화하세요 — 하이픈 있음 · 소문자가 가장 일반적이고 RFC 의 권장에도 부합합니다. API 로 받은 값은 비교나 저장 전에 반드시 toLowerCase() 를 통과시키세요. 데이터베이스에 저장한다면 문자열이 아니라 바이너리 타입 또는 uuid 타입을 쓰는 것이 근본적인 해결입니다 — 바이너리라면 표기의 문제 자체가 존재하지 않습니다(PostgreSQL 의 uuid 타입은 입력의 표기를 흡수해 같은 값으로 다룹니다). 그리고 UUID 를 받는 곳에는 타당성 검증을 넣으세요 — 형식이 다른 값이 왔을 때 조용히 다른 레코드를 만드는 것이 아니라 그 자리에서 에러로 하는 편이 원인을 쫓기 쉬워집니다. |
충돌에 대해서는 지나치게 걱정하는 것도 지나치게 걱정하지 않는 것도 잘못입니다. UUID v4 의 랜덤 부분은 122 비트이며 매초 10 억 개를 100 년간 계속 생성해도 충돌 확률은 무시할 수 있을 만큼 낮습니다 — 다만 이는 암호학적으로 안전한 난수를 쓰고 있는 경우에 한정된 이야기입니다. Math.random() 을 바탕으로 UUID 를 조립하는 구현은 실재하며 그런 구현에서는 실제로 충돌합니다 — 특히 임베디드 기기나 기동 직후의 서버는 엔트로피가 부족하기 쉬워 여러 대가 같은 값을 생성한 사례가 있습니다. 브라우저라면 crypto.randomUUID(), 서버라면 각 언어의 암호용 난수 API 를 쓰세요. 한 가지 더, crypto.randomUUID() 는 시큐어 컨텍스트(HTTPS 또는 localhost)에서만 쓸 수 있습니다 — 사내의 HTTP 환경에서 왜인지 함수가 존재하지 않는다는 것은 거의 이것이 원인입니다.
📖 사용법
-
1
생성 수 지정생성 수에 1~100을 입력합니다.
-
2
하이픈 유무 선택 후 생성하이픈 없음을 선택하고 생성 버튼을 클릭합니다.
-
3
일괄 복사 사용일괄 복사 버튼으로 모든 UUID를 복사합니다.
❓ 자주 묻는 질문
UUID v4란?
충돌(중복) 가능성이 있나요?
UUID를 데이터베이스 기본 키로 사용할 수 있나요?
🐛 이 도구에서 문제가 발생했나요?
무료 · 가입 불필요. 재현 절차만이라도 도움이 됩니다. 보고는 운영자에게 직접 전달되어 개선에 사용됩니다.
보고 감사합니다!
운영자에게 전달되었습니다. 개선에 사용됩니다.