NanoID Generator
Generate tiny URL-safe unique IDs with customizable alphabet
Алфавит
Размер
Количество
Нажмите «Сгенерировать» для создания NanoID
Что такое NanoID?
NanoID — небольшая, безопасная, URL-дружественная библиотека генерации уникальных строк для JavaScript. Использует криптографически защищённый генератор случайных чисел без внешних зависимостей.
По умолчанию NanoID использует 64-символьный URL-безопасный алфавит (A-Za-z0-9_-) и генерирует ID длиной 21 символ — ~126 бит энтропии, сопоставимо с UUID v4, но компактнее.
NanoID против UUID
Сравнение NanoID (по умолчанию) и UUID v4:
| Свойство | NanoID (по умолчанию) | UUID v4 |
|---|---|---|
| Длина | 21 символ | 36 символов (с дефисами) / 32 (без) |
| Алфавит | 64 символа (A-Za-z0-9_-) | 16 символов (hex: 0-9a-f) |
| Биты энтропии | ~126 бит | 122 бита |
| URL-безопасный | Да | Да (только hex) |
| Стандарт | Нет стандарта | RFC 4122 / RFC 9562 |
| Дефисы | Нет | Да (формат 8-4-4-4-12) |
| Нативная поддержка в браузере | Нет (нужен пакет npm) | Да (<code>crypto.randomUUID()</code>) |
| Источник случайности | CSPRNG (Web Crypto / Node.js Crypto) | CSPRNG (Web Crypto / Node.js Crypto) |
Выбирайте NanoID для более коротких ID и пользовательских алфавитов. UUID v4 — для совместимости со стандартом.
Размеры и вероятности коллизий
Вероятность коллизии зависит от длины ID и размера алфавита:
| Размер | Алфавит | Безопасность коллизий |
|---|---|---|
| 6 | 64 | ~2 в год |
| 8 | 64 | ~6 тысяч лет |
| 11 | 64 | ~2 млн лет |
| 16 | 64 | ~7 тысяч лет |
| 21 | 64 | ~139 лет |
| 32 | 64 | ~2 года |
| 36 | 36 | ~7 часов |
Используйте калькулятор NanoID для точных вероятностей для вашего варианта использования.
Пользовательские алфавиты
NanoID поддерживает настраиваемые алфавиты:
A-Za-z0-9_-A-Za-z0-90-9a-f0-9Убедитесь в достаточном количестве символов для желаемой безопасности коллизий.
Источник случайности
NanoID использует CSPRNG платформы:
Устранение смещения
Когда алфавит не является степенью 2, прямое использование случайных байт даёт смещение. NanoID устраняет его алгоритмом отклонения.
Алгоритм отклонения NanoID:
- Вычислить минимальную битовую маску для алфавита.
- Генерировать случайные байты и применять маску.
- Принять значение только если оно меньше размера алфавита; иначе — повторить.
Гарантирует равномерное распределение без смещения.
// 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 — Установка
// 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"Только браузер (без зависимостей)
Реализация эквивалента NanoID без зависимостей:
// 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 — специфичный синтаксис
// 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
}