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
}