--- title: "official-doc / NanoID — A tiny, secure, URL-friendly unique string ID generator" source_type: official-doc url: https://github.com/ai/nanoid archive_url: vendor: ai (Andrey Sitnik) related_branches: [feature-resource-identifier-contract] related_projects: [ca-skeleton] tags: [official-doc, ca-skeleton, api-design, fetch-spec, clean-architecture] created: 2026-05-31 last_reviewed: 2026-05-31 status: raw confidence: medium --- # official-doc / NanoID — A tiny, secure, URL-friendly unique string ID generator > Layer: `raw/official-docs/` — NanoID 프로젝트 README 원문 발췌·출처 기록. > 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 별도 작성. 원본은 raw에 영구 보관. > **주의**: 이 자료는 GitHub 프로젝트 README (project-level documentation) 이며 IETF 표준이나 공식 벤더 spec 이 아니다. 규범적 강제력은 없으나 de facto 채택 수준은 높다. ## Parent / 활용 branch (필수, 최소 1개+) | Branch | 이 자료가 정당화하는 결정 | |---|---| | [[raw/branch-notes/feature-resource-identifier-contract]] | D1 (resource ID default 형식 후보로서 NanoID 근거), D2 (64자 URL-safe 알파벳 `A-Za-z0-9_-` charset 근거), D3 (URL-safe-by-default 속성 근거), D9 (crypto module / hardware random generator 사용 = SecureRandom 의무 근거) | ## 출처 / Source - 원본 URL: https://github.com/ai/nanoid - 아카이브 URL: (미확인 — archive.org 스냅샷 별도 확보 권장) - 저자 / 조직: Andrey Sitnik (ai) — Evil Martians - 발행일: 프로젝트 첫 릴리즈 2017년경, README 지속 업데이트 중 - 마지막 확인일: 2026-05-31 ## 왜 저장했는지 / Why archived `feature-resource-identifier-contract` 의 D1 ~ D9 결정에서 NanoID 는 UUID v4 / UUID v7 / ULID 와 함께 resource ID 후보로 검토된다. NanoID 의 21자 기본 길이·URL-safe 알파벳·crypto 기반 SecureRandom·UUID v4 와의 충돌 확률 동등성을 이 README 가 직접 명시하므로, 해당 결정의 Evidence quote 원천으로 보관한다. ## 핵심 인용 / Key quotes (verbatim, 5문장) > [§ 프로젝트 설명 — README line 8] "A tiny, secure, URL-friendly, unique string ID generator for JavaScript." > [§ Comparison with UUID — README lines 67–68] "For there to be a one in a billion chance of duplication, > 103 trillion version 4 IDs must be generated." > [§ Comparison with UUID — README lines 72–73] "Nano ID uses a bigger alphabet, so a similar number of random bits > are packed in just 21 symbols instead of 36." > [§ API / Blocking — README lines 195–196] "By default, Nano ID uses URL-friendly symbols (`A-Za-z0-9_-`) and returns an ID > with 21 characters (to have a collision probability similar to UUID v4)." > [§ Security — README lines 107–109] "**Unpredictability.** Instead of using the unsafe `Math.random()`, Nano ID > uses the `crypto` module in Node.js and the Web Crypto API in browsers. > These modules use unpredictable hardware random generator." ## Claims Extracted / 추출된 주장 > 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다. | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | NANOID-C1 | NanoID 의 기본 ID 길이는 21자이며, UUID v4 와 유사한 충돌 확률을 가지도록 설계되었다 | [§ API/Blocking, line 195–196] "By default, Nano ID uses URL-friendly symbols (`A-Za-z0-9_-`) and returns an ID with 21 characters (to have a collision probability similar to UUID v4)." | `official-reference` | NanoID 라이브러리의 기본 설정 (모든 지원 언어 포트에서는 포트별 검증 필요) | 특정 애플리케이션에서의 충돌 확률이 UUID v4 와 실제로 동일하다는 것 (비트 분포 동일성만 주장, 구현 품질 동일성 아님) | | NANOID-C2 | NanoID 의 기본 알파벳은 `A-Za-z0-9_-` (64자 URL-safe 문자)이다 | [§ API/Blocking, line 195] "By default, Nano ID uses URL-friendly symbols (`A-Za-z0-9_-`)" | `official-reference` | NanoID JS 라이브러리 기본 설정 | 모든 포트 언어의 기본 알파벳이 동일하다는 것; RFC 3986 `unreserved` 문자셋 전체와 동일하지는 않음 (`~` 제외) | | NANOID-C3 | NanoID 는 UUID v4 와 유사한 126 random bits 를 포함하며, 10억 분의 1 충돌 확률을 달성하려면 103조 개의 UUID v4 ID 가 필요하다 | [§ Comparison with UUID, line 67–68] "For there to be a one in a billion chance of duplication, 103 trillion version 4 IDs must be generated." | `official-reference` | NanoID JS (동일 비트 수 기반의 비교) | NanoID 와 UUID v4 의 충돌 확률이 수학적으로 동일하다는 것 (NanoID 126bit, UUID v4 122bit — README 본문 명시); 모든 사용 환경에서 동일한 분포 보장 | | NANOID-C4 | NanoID 는 `Math.random()` 대신 Node.js `crypto` 모듈 또는 Web Crypto API (브라우저) 를 사용하여 예측 불가능한 하드웨어 난수를 생성한다 | [§ Security, line 107–109] "Instead of using the unsafe `Math.random()`, Nano ID uses the `crypto` module in Node.js and the Web Crypto API in browsers. These modules use unpredictable hardware random generator." | `official-reference` | NanoID JS 의 기본 (`nanoid` import) 사용 시 | `nanoid/non-secure` 변형에는 적용되지 않음; JVM / Go 등 다른 언어 포트의 구현 동일성 보장 안 됨 | | NANOID-C5 | NanoID 는 `customAlphabet(alphabet, size)` API 로 알파벳과 ID 길이를 커스터마이징할 수 있으며, 알파벳은 최대 256자까지 허용된다 | [§ Custom Alphabet or Size, line 238–239] "`customAlphabet` returns a function that allows you to create `nanoid` with your own alphabet and ID size." | `official-reference` | NanoID JS 5.x (ESM) 기준 | 커스텀 알파벳 사용 시 충돌 확률이 기본값과 동일하다는 것; 256자 초과 알파벳 사용 시 내부 알고리즘 보안 보장 없음 (README 명시) | ### Strength 허용값 - `official-reference` — 공식 reference/API 문서 (본 자료는 GitHub 프로젝트 README — 벤더 공식 문서 수준) ## Usage Boundaries / 적용 경계 - 이 자료가 직접 증명하는 것: - `NANOID-C1`: NanoID JS 기본 길이가 21자임 - `NANOID-C2`: NanoID JS 기본 알파벳이 `A-Za-z0-9_-` (64자 URL-safe) 임 - `NANOID-C3`: 기본 설정에서 UUID v4 와 유사한 충돌 확률 (10억 분의 1 달성에 103조 개 필요) 을 가짐 - `NANOID-C4`: NanoID JS 기본 import 는 `Math.random()` 이 아닌 `crypto` 모듈 / Web Crypto API 를 사용함 - `NANOID-C5`: `customAlphabet(alphabet, size)` API 로 알파벳과 길이를 커스터마이징 가능 - 이 자료가 증명하지 않는 것: - NanoID 가 특정 Java / Kotlin / Go 포트에서도 동일한 보안 특성을 가진다는 것 (포트별 독립 검증 필요) - `nanoid/non-secure` 변형이 SecureRandom 의무를 만족한다는 것 (만족하지 않음 — README 명시) - NanoID 알파벳 (`A-Za-z0-9_-`) 이 RFC 3986 `unreserved` 전체와 동일하다는 것 (`~` 문자가 `unreserved` 에 포함되나 NanoID 기본 알파벳에는 없음) - NanoID 가 time-ordered ID 를 생성한다는 것 (생성하지 않음 — UUID v4 와 동일한 랜덤, DB index 성능은 UUID v4 수준) - 이 README 가 IETF 표준 또는 공식 vendor spec 수준의 규범적 강제력을 가진다는 것 - 내 프로젝트 (ca-skeleton) 에 적용하려면 추가 확인이 필요한 것: - Java / Kotlin 포트 (`nanoid-java` 등) 의 `SecureRandom` 사용 여부 — JVM 포트 README 별도 확인 필수 - PostgreSQL / MySQL 에서 NanoID varchar(21) 의 B-tree index 성능 — UUID v4 와 동일한 랜덤 분포이므로 page split 위험 존재 (time-ordered ID 와 달리) - OpenAPI 3.1 에서 NanoID 형식 표현 방법 (`format: nanoid` 는 표준 없음 — `pattern` 으로 표현 필요) - `feature-security-operational-baseline` 에서 `SecureRandom` 의무와 NanoID JS 포트가 정합하는지 ## 메모 / Notes - NanoID 는 time-ordered ID 가 아니므로 D10 (DB primary key 정책) 에서 UUID v4 와 동일한 약점 (B-tree page split) 을 가진다. D1 결정 시 DB 성능 요구사항이 높다면 UUID v7 / ULID 가 더 적합할 수 있다. - README 에 명시된 벤치마크: `nanoid` JS 기준 ~4.9M ops/sec (Framework 13 7840U, Node.js 21.6). `crypto.randomUUID()` 는 ~14M ops/sec 로 NanoID 보다 빠름 — 성능 우선 시 `crypto.randomUUID()` (UUID v4) 가 유리하나 ID 길이는 36자로 길어짐. - Claim 강도: 이 자료는 `official-reference` 로 분류했으나, IETF RFC (예: RFC 9562 UUID) 나 NIST 표준이 아닌 GitHub README 이므로 규범적 weight 는 낮다. 충돌 확률 수치 등은 외부 공식 분석으로 보강 권장. - NanoID 는 20개 이상의 언어로 포팅되어 있으나, 각 포트의 보안 특성은 독립적으로 검증해야 한다. ## Related / 관련 - 같은 주제 다른 official-doc (예정): - [[raw/official-docs/rfc9562-uuid]] — UUID v4 / v7 공식 표준 (IETF RFC 9562, 2024) - [[raw/official-docs/ulid-spec]] — ULID 공식 spec (26자 base32, monotonic) - [[raw/official-docs/cuid2-spec]] — CUID2 (timestamp leak 없는 보안 중심 ID) - 이 자료를 인용한 wiki 요약: (생성 시 추가)