Generatore NanoID
Genera ID unici compatti e sicuri per URL con alfabeto personalizzabile
Alfabeto
Dimensione
Quantità
Clicca su Genera per creare NanoID
Cos'è NanoID?
NanoID è un generatore di ID casuali piccolo, veloce e URL-safe. Per default produce stringhe di 21 caratteri usando un alfabeto di 64 caratteri (A-Za-z0-9_-), fornendo circa 126 bit di entropia — paragonabile ai 122 bit di UUID v4 ma in una stringa più corta.
NanoID non incorpora un timestamp o dati strutturati. Ogni ID è puramente casuale, generato dal generatore di numeri casuali crittograficamente sicuro del sistema operativo (crypto.getRandomValues() nei browser, crypto.randomBytes() in Node.js).
NanoID vs UUID v4
NanoID e UUID v4 sono entrambi generatori di ID casuali supportati da un CSPRNG. Differiscono nel formato, nella lunghezza e nel supporto dell'ecosistema:
| Proprietà | NanoID (predefinito) | UUID v4 |
|---|---|---|
| Formato | Alfanumerico URL-safe + _- | Esadecimale con trattini |
| Lunghezza | 21 caratteri (predefinito) | 36 caratteri |
| Entropia | ~126 bit | 122 bit |
| URL-safe | Sì — nessuna codifica necessaria | Sì (con trattini) |
| Alfabeto | 64 caratteri (A-Za-z0-9_-) | 16 caratteri (0-9a-f) |
| Dipendenze | Richiede pacchetto npm | Nativo (crypto.randomUUID) |
| Personalizzabile | Sì — lunghezza e alfabeto | No |
| Standard | Nessuno (libreria comunitaria) | RFC 4122 / RFC 9562 |
Scegliere UUID v4 quando l'interoperabilità con sistemi esterni conta — database con colonne UUID native, API che si aspettano il formato UUID o infrastruttura di logging che analizza UUID. Scegliere NanoID quando si vogliono ID più corti e si controlla lo stack completo.
Probabilità di collisione per dimensione
La probabilità di collisione di NanoID dipende dalla lunghezza dell'ID e dal tasso di generazione. La seguente tabella usa l'alfabeto di 64 caratteri predefinito:
| Dimensione (chars) | ID possibili | Sicurezza collisione |
|---|---|---|
| 6 | 64 | ~1 su 4,5 miliardi — sicuro per qualche migliaio di ID |
| 8 | 64 | ~1 su 4,5 trilioni — sicuro per milioni di ID |
| 11 | 64 | ~1 su 2,8 quadrilioni — sicuro per miliardi di ID |
| 16 | 64 | ~1 su 1,2 × 10^19 — sicuro per trilioni di ID |
| 21 | 64 | ~1 su 10^30 — sicuro per 100 miliardi di ID al giorno per secoli |
| 32 | 64 | Paragonabile a UUID v4 (122 bit) |
| 36 | 36 | Supera UUID v4 |
La dimensione predefinita di 21 caratteri è scelta per corrispondere alla resistenza alle collisioni di UUID v4 (~126 bit) pur essendo il 41% più corta. Per la maggior parte delle applicazioni, 21 caratteri è la scelta giusta.
Alfabeti personalizzati
L'alfabeto di NanoID è completamente personalizzabile. La libreria accetta qualsiasi stringa di caratteri univoci come alfabeto e genera ID usando solo quei caratteri:
A-Za-z0-9_-A-Za-z0-90-9a-f0-9Importante: usare nanoid/non-secure solo per applicazioni non sensibili alla sicurezza (es. ID elementi UI). Per qualsiasi ID che deve essere impossibile da indovinare, usare sempre l'import sicuro predefinito.
Come NanoID genera la casualità
NanoID usa il generatore di numeri pseudo-casuali crittograficamente sicuro (CSPRNG) del sistema operativo. Nei browser è crypto.getRandomValues(); in Node.js è crypto.randomFillSync(). Questa è la stessa fonte di entropia usata per le chiavi di sessione TLS — molto più forte di Math.random().
Campionamento per rifiuto (evitare il bias modulo)
Un approccio ingenuo per generare caratteri casuali sarebbe: prendere un byte casuale (0-255) e calcolare byte % dimensioneAlfabeto. Questo introduce un bias modulo — alcuni caratteri appaiono leggermente più spesso di altri quando la dimensione dell'alfabeto non divide uniformemente 256.
NanoID elimina questo bias usando il campionamento per rifiuto:
- Determinare la maschera potenza-di-due più piccola che copre la dimensione dell'alfabeto (es. per un alfabeto di 64 chars, la maschera è 63 = 0b00111111)
- Generare byte casuali e applicare la maschera:
byte & maschera - Se il valore mascherato è nell'intervallo dell'alfabeto, usarlo. Altrimenti, scartare e riprovare.
Questo significa che alcuni byte casuali vengono scartati, ma il risultato è una distribuzione perfettamente uniforme sull'alfabeto — nessun carattere è più probabile di un altro.
// 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"Supporto ambiente
Esempi di codice
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"Browser (CDN)
NanoID può essere usato direttamente nel browser tramite un import CDN. Nessun passaggio di build richiesto per la prototipazione rapida.
// 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
}