NanoIDジェネレーター
Generate tiny URL-safe unique IDs with customizable alphabet
アルファベット
サイズ
件数
「生成」をクリックして NanoID を作成
NanoID とは何ですか?
NanoID は小さく、高速で、URL セーフなランダム ID ジェネレーターです。デフォルトでは 64 文字のアルファベット(A-Za-z0-9_-)を使用して 21 文字の文字列を生成し、約 126 ビットのエントロピーを提供します——UUID v4 の 122 ビットに匹敵しますが、より短い文字列です。
NanoID はタイムスタンプや構造化されたデータを埋め込みません。各 ID は完全にランダムで、オペレーティングシステムの暗号学的に安全な乱数生成器(ブラウザでは crypto.getRandomValues()、Node.js では crypto.randomBytes())によって生成されます。
NanoID vs UUID v4
NanoID と UUID v4 はどちらも CSPRNG に支援されたランダム ID ジェネレーターです。フォーマット、長さ、エコシステムサポートにおいて異なります:
| プロパティ | NanoID(デフォルト) | UUID v4 |
|---|---|---|
| フォーマット | URL セーフ英数字 + _- | ハイフン付き 16 進数 |
| 長さ | 21 文字(デフォルト) | 36 文字 |
| エントロピー | 〜126 ビット | 122 ビット |
| URL セーフ | はい——エンコーディング不要 | はい(ハイフン付き) |
| アルファベット | 64 文字(A-Za-z0-9_-) | 16 文字(0-9a-f) |
| 依存関係 | npm パッケージが必要 | ネイティブ(crypto.randomUUID) |
| カスタマイズ可能 | はい——長さとアルファベット | いいえ |
| 標準 | なし(コミュニティライブラリ) | RFC 4122 / RFC 9562 |
外部システムとの相互運用性が重要な場合は UUID v4 を選択してください——ネイティブ UUID カラムを持つデータベース、UUID フォーマットを期待する API、または UUID を解析するログインフラ。短い ID が必要でスタック全体を制御する場合は NanoID を選択してください。
サイズ別衝突確率
NanoID の衝突確率は ID の長さと生成レートによって異なります。以下の表はデフォルトの 64 文字アルファベットを使用します:
| サイズ(文字) | 可能な ID 数 | 衝突安全性 |
|---|---|---|
| 6 | 64 | 〜1 / 45 億——数千 ID には安全 |
| 8 | 64 | 〜1 / 4.5 兆——数百万 ID には安全 |
| 11 | 64 | 〜1 / 2.8 千兆——数十億 ID には安全 |
| 16 | 64 | 〜1 / 1.2 × 10^19——数兆 ID には安全 |
| 21 | 64 | 〜1 / 10^30——数百年間毎日 1000 億 ID に安全 |
| 32 | 64 | UUID v4 に匹敵(122 ビット) |
| 36 | 36 | UUID v4 を超える |
デフォルトの 21 文字サイズは、41% 短くしながら UUID v4 の衝突耐性(〜126 ビット)に一致するように選ばれています。ほとんどのアプリケーションでは 21 文字が適切な選択です。
カスタムアルファベット
NanoID のアルファベットは完全にカスタマイズ可能です。ライブラリは一意の文字の任意の文字列をアルファベットとして受け入れ、それらの文字のみを使用して ID を生成します:
A-Za-z0-9_-A-Za-z0-90-9a-f0-9重要:セキュリティに敏感でないアプリケーション(例:UI 要素 ID)にのみ nanoid/non-secure を使用してください。推測不可能な必要のある ID には、常にデフォルトのセキュアインポートを使用してください。
NanoID がランダム性を生成する方法
NanoID はオペレーティングシステムの暗号学的に安全な擬似乱数生成器(CSPRNG)を使用します。ブラウザでは crypto.getRandomValues()、Node.js では crypto.randomFillSync() です。これは TLS セッション鍵に使用されるのと同じエントロピーソースです——Math.random() よりはるかに強力です。
拒否サンプリング(モジュロバイアスの回避)
ランダムな文字を生成するナイーブなアプローチは:ランダムバイト(0–255)を取り、byte % alphabetSize を計算することです。アルファベットサイズが 256 を均等に割り切れない場合、これはモジュロバイアスを導入します——一部の文字が他の文字よりわずかに多く現れます。
NanoID は拒否サンプリングを使用してこのバイアスを排除します:
- アルファベットサイズをカバーする最小の 2 のべき乗マスクを決定する(例:64 文字のアルファベットの場合、マスクは 63 = 0b00111111)
- ランダムバイトを生成してマスクを適用する:
byte & mask - マスクされた値がアルファベットの範囲内にある場合、使用します。そうでない場合、破棄して再試行します。
これは一部のランダムバイトが破棄されることを意味しますが、結果はアルファベット上で完全に均一な分布です——どの文字も他の文字より多く出現しません。
// Pure browser — no npm package needed
function generateNanoid(alphabet, size) {
const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
const step = Math.ceil((1.6 * mask * size) / alphabet.length)
let id = ''
while (id.length < size) {
const bytes = crypto.getRandomValues(new Uint8Array(step))
for (const byte of bytes) {
const idx = byte & mask
if (idx < alphabet.length) {
id += alphabet[idx]
if (id.length === size) break
}
}
}
return id
}
const URL_SAFE = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
generateNanoid(URL_SAFE, 21) // → "V1StGXR8_Z5jdHi6B-myT"環境サポート
コード例
JavaScript / TypeScript
// npm i nanoid
import { nanoid } from 'nanoid'
nanoid() // → "V1StGXR8_Z5jdHi6B-myT" (21 chars, URL-safe)
nanoid(8) // → "Uakgb_J5" (custom size)
// Custom alphabet
import { customAlphabet } from 'nanoid'
const hexId = customAlphabet('0123456789abcdef', 16)
hexId() // → "4f3a1b8c9d2e0f7a"
const numId = customAlphabet('0123456789', 8)
numId() // → "30812894"ブラウザ(CDN)
NanoID は CDN インポートを通じてブラウザで直接使用できます。クイックプロトタイピングにビルドステップは不要です。
// Pure browser — no npm package needed
function generateNanoid(alphabet, size) {
const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
const step = Math.ceil((1.6 * mask * size) / alphabet.length)
let id = ''
while (id.length < size) {
const bytes = crypto.getRandomValues(new Uint8Array(step))
for (const byte of bytes) {
const idx = byte & mask
if (idx < alphabet.length) {
id += alphabet[idx]
if (id.length === size) break
}
}
}
return id
}
const URL_SAFE = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
generateNanoid(URL_SAFE, 21) // → "V1StGXR8_Z5jdHi6B-myT"Python
# pip install nanoid
from nanoid import generate
generate() # → "V1StGXR8_Z5jdHi6B-myT"
generate(size=8) # → "Uakgb_J5"
generate('0123456789abcdef', 16) # custom alphabet + sizeNode.js(CommonJS)
// Node.js — stdlib only, no npm needed
const { randomFillSync } = require('crypto')
function nanoid(alphabet, size) {
const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
const step = Math.ceil((1.6 * mask * size) / alphabet.length)
let id = ''
while (id.length < size) {
const bytes = randomFillSync(Buffer.alloc(step))
for (const byte of bytes) {
const idx = byte & mask
if (idx < alphabet.length) { id += alphabet[idx]; if (id.length === size) break }
}
}
return id
}