·5분 읽기
UUID v4 충돌 확률 — 36억개 만들면 진짜 충돌? 실측 5가지
UUID v4 충돌은 실제로 일어날까? 122비트 랜덤·생일 역설·2.71 quintillion 50% 임계점·실측 100M 테스트·DB 유니크 인덱스 5가지 시나리오 정리.

🆔
UUID 생성기 바로 사용하기
고유한 UUID를 생성하세요
→
UUID v4 충돌 — 실제로 가능한가요?
신입 개발자가 자주 묻는 질문. "UUID v4 두 번 만들면 같은 게 나올 수 있어요?" 답은 "이론상 가능, 현실상 거의 불가능".
핵심 숫자.
- UUID v4는 128비트 중 6비트가 버전·variant 표시 → **랜덤 비트 122비트**
- 가능한 UUID 수: 2^122 ≈ 5.3 × 10^36 (약 5.3 undecillion)
- 50% 충돌 확률 도달 시점: **2.71 quintillion(2.71 × 10^18)개** 생성
- 1초에 10억 개씩 만들어도 86년 걸려야 50% 도달
오늘 정리할 5가지 시나리오.
1. 생일 역설 수식 — 충돌 확률 계산법
2. 36억(3.6 × 10^9) 개 만들면? — 일반 서비스 규모
3. 100M(1억) 실측 — FastUUID 보고
4. PRNG 약점 — Math.random() 위험
5. DB 유니크 인덱스 — 만일에 대비
공식 출처는 [Wikipedia UUID 항목](https://en.wikipedia.org/wiki/Universally_unique_identifier) 및 [The Birthday Paradox in Production](https://tomarcher.io/posts/birthday-paradox/) 분석 글 참고.
시나리오 1) 생일 역설 — 50% 충돌 확률 수식
방에 23명만 있어도 생일 같은 사람이 있을 확률이 50% 넘어요. 이게 생일 역설(Birthday Paradox).
UUID 충돌도 같은 수학.
수식.
- N = 가능한 UUID 수 = 2^122
- n = 생성한 UUID 수
- 충돌 확률 P ≈ 1 - exp(-n²/(2N))
50% 도달 임계.
- n²/(2N) ≈ 0.693 (ln 2)
- n ≈ √(2N × 0.693) ≈ √(2^122 × 1.386)
- ≈ 2.71 × 10^18 = **2.71 quintillion**
비교 감각.
- 인류 인구 80억 ≈ 8 × 10^9
- 인류 1인당 3억 4천만 개 만들어야 50% 도달
- 1나노초마다 한 개 만들어도 2,710억 초 ≈ 8,600년
낮은 확률. 1 in 1 billion(10억분의 1) 충돌.
- n ≈ 103 trillion(1.03 × 10^14)
- 즉 103조 개 만들어도 충돌 1/10억
실용 결론. 일반 서비스에서 UUID v4 충돌 신경 쓸 필요 거의 없음.
시나리오 2) 36억 개 — 일반 서비스 규모
스타트업·중견 서비스 1년 생성량 추정.
- 사용자 100만 × 1인당 일일 활동 1,000건 × 365일 = 3.65 × 10^11 (3,650억)
- 보통 서비스는 이보다 훨씬 적음 (수억~수십억)
36억 개(3.6 × 10^9) 만들 때 충돌 확률.
- P ≈ 1 - exp(-(3.6e9)² / (2 × 5.3e36))
- ≈ 1 - exp(-1.22 × 10^-18)
- ≈ **1.22 × 10^-18 (1.22 quintillionth)**
비교.
- 벼락 맞을 확률 (평생): 1 / 12,000 = 8.3 × 10^-5
- UUID 36억 개 충돌: 1.22 × 10^-18
- → 충돌이 벼락 맞기보다 6.8 × 10^13배 어려움
100억 개(10^10) 만들어도 P ≈ 9.4 × 10^-18. 여전히 무시 가능.
결론. 토스·카카오뱅크급 서비스도 UUID v4 충돌 걱정 X. 단 실제 PRNG 품질이 충분히 균일해야 함.
시나리오 3) 100M 실측 — FastUUID 보고서
[FastUUID 100M 테스트](https://fastuuid.com/learn-about-uuids/100-million-uuids-collisions)에서 1억 개 UUID v4 생성 후 충돌 검사. 결과 **3건 충돌** 발견.
잠깐, 수학적으로는?
- n = 10^8
- 예상 충돌 = n² / (2N) ≈ 10^16 / 1.06 × 10^37 ≈ 9.4 × 10^-22
- 1억 개로는 충돌 0건이 정상
그런데 3건? 이유.
- **PRNG 약점**: 일부 언어·라이브러리의 기본 난수 생성기가 균일하지 않음
- **시드 충돌**: 같은 시간에 같은 시드로 시작되면 같은 UUID
- **버그**: UUID 라이브러리 초기화 버그
검증 환경.
- Java SecureRandom: 충돌 0건
- Python uuid.uuid4(): 충돌 0건
- Node.js crypto.randomUUID(): 충돌 0건
- 일부 비표준 라이브러리: 드물게 발생
교훈. **표준 라이브러리** 사용. 직접 구현 X. Math.random() 기반 UUID는 절대 X.
시나리오 4) Math.random() 함정 — 절대 쓰지 마세요
JavaScript에서 옛날 코드.
```javascript
// ❌ 위험한 UUID 생성기
function badUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
```
문제.
1. `Math.random()`은 PRNG (Pseudo Random Number Generator) — 시드만 알면 예측 가능
2. V8 엔진은 xorshift128+ 사용. 보안 난수 X
3. 충돌 자체는 드물지만 **예측 가능 = 보안 위험**
4. UUID로 인증 토큰·세션 ID 만들면 공격 가능
안전한 대체.
```javascript
// ✅ Web Crypto API 사용 (브라우저·Node 18+)
const uuid = crypto.randomUUID();
// 'a3b1c2d4-...' 형식, 암호학적으로 안전
// ✅ Node.js 14+ 외부 라이브러리
const { v4: uuidv4 } = require('uuid');
const id = uuidv4();
```
구분.
- Math.random() = 게임 주사위·UI 애니메이션 OK
- crypto.randomUUID() = 사용자 식별·세션 토큰
2019년 이후 보안 사고 다수가 "Math.random() 기반 토큰" 원인. UUID 생성에는 **반드시** Web Crypto 또는 표준 라이브러리.
시나리오 5) DB 유니크 인덱스 — 만일에 대비
수학적 충돌 확률 1/10^18이라도 PRNG 버그·시드 사고로 충돌 가능. 안전망은 데이터베이스 유니크 인덱스.
PostgreSQL.
```sql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL
);
-- PRIMARY KEY = 자동 UNIQUE 인덱스
```
MongoDB.
```javascript
db.users.createIndex({ uuid: 1 }, { unique: true });
```
충돌 시 동작.
- INSERT 시 PostgreSQL: `duplicate key violates unique constraint` 에러 (PG 23505)
- MongoDB: `E11000 duplicate key` 에러
- 애플리케이션: 에러 캐치 → UUID 재생성 → 재시도
재시도 로직.
```python
for attempt in range(3):
try:
new_id = str(uuid.uuid4())
db.execute('INSERT INTO users (id, email) VALUES (?, ?)',
(new_id, email))
break
except IntegrityError as e:
if 'unique' in str(e) and attempt < 2:
continue # UUID 재생성 후 재시도
raise
```
실무. 1억 INSERT 중 충돌 0~3건이라도 재시도 로직 있으면 자동 복구. UUID 자체는 안전한 ID 체계지만 **DB 레벨 검증**이 마지막 안전장치.
관련해서 [UUID 데이터베이스 키 토큰 가이드](/blog/uuid-generator-database-keys-tokens-guide)에서 PK·세션 토큰 활용을, [UUID v7 PostgreSQL 마이그레이션](/blog/uuid-v7-postgres-mongodb-migration-2026)에서 시간순 정렬 가능한 UUID v7 도입을 이어 보세요.
Toolkio UUID 생성기 — 표준 RFC 9562 보장
[Toolkio UUID 생성기](https://toolkio.com/tools/uuid-generator)는 Web Crypto API 기반. RFC 9562 표준 v4 보장.
특징.
1. 브라우저 `crypto.randomUUID()` 호출 (V8·Spider Monkey·JavaScriptCore 모두 CSPRNG)
2. 암호학적으로 안전한 난수
3. Math.random() 절대 사용 X
4. v1·v4·v7 동시 지원 (옵션 선택)
사용 시.
- 단일 생성: 한 번 클릭으로 1개
- 대량 생성: 100개·1000개 한 번에 (CSV 다운로드)
- 형식 옵션: 하이픈 포함/제외, 대소문자
참고. UUID v4 충돌 확률은 사실상 0이지만 보안 토큰으로 쓸 때는 추가 검증 필요. 인증·세션은 더 긴 시크릿 (256비트 이상) 권장. UUID v4는 122비트 엔트로피.
결론. 일반 서비스 PK·식별자로는 UUID v4 충분. 보안 토큰은 별도 시크릿. DB 유니크 인덱스 무조건 걸기. 이 3가지면 충돌 걱정 끝.