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
FormatoAlfanumerico URL-safe + _-Esadecimale con trattini
Lunghezza21 caratteri (predefinito)36 caratteri
Entropia~126 bit122 bit
URL-safeSì — nessuna codifica necessariaSì (con trattini)
Alfabeto64 caratteri (A-Za-z0-9_-)16 caratteri (0-9a-f)
DipendenzeRichiede pacchetto npmNativo (crypto.randomUUID)
PersonalizzabileSì — lunghezza e alfabetoNo
StandardNessuno (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 possibiliSicurezza collisione
664~1 su 4,5 miliardi — sicuro per qualche migliaio di ID
864~1 su 4,5 trilioni — sicuro per milioni di ID
1164~1 su 2,8 quadrilioni — sicuro per miliardi di ID
1664~1 su 1,2 × 10^19 — sicuro per trilioni di ID
2164~1 su 10^30 — sicuro per 100 miliardi di ID al giorno per secoli
3264Paragonabile a UUID v4 (122 bit)
3636Supera 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:

Solo numericoA-Za-z0-9_-
Usare '0123456789' per ID composti solo da cifre — utile per codici SMS o identificatori stile PIN.
Esadecimale minuscoloA-Za-z0-9
Usare '0123456789abcdef' per stringhe esadecimali compatte senza il formato con trattini UUID.
Leggibile dall'uomo0-9a-f
Escludere caratteri visivamente ambigui (0, O, 1, I, l) per ID che gli utenti potrebbero dover digitare manualmente.
Dominio personalizzato0-9
Usare qualsiasi insieme di caratteri appropriato all'applicazione — es. solo vocali+consonanti per ID pronunciabili.

Importante: 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:

  1. 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)
  2. Generare byte casuali e applicare la maschera: byte & maschera
  3. 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.

How the algorithm works — step by step
// 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

Browser
Browser moderni (Chrome 37+, Firefox 34+, Safari 7+) — usa crypto.getRandomValues()
Node.js 14+
Node.js 14.18+ — usa crypto.randomFillSync()
Deno
Deno — usa crypto.getRandomValues()
Bun
React Native — usa il polyfill expo-crypto o react-native-get-random-values
Edge / Cloudflare Workers
Runtime edge (Cloudflare Workers, Vercel Edge) — API Web Crypto disponibile
React Native
Bun — supporto crypto nativo

Esempi di codice

JavaScript / TypeScript

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"

Browser (CDN)

NanoID può essere usato direttamente nel browser tramite un import CDN. Nessun passaggio di build richiesto per la prototipazione rapida.

JavaScript
// 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

Python
# pip install nanoid
from nanoid import generate

generate()              # → "V1StGXR8_Z5jdHi6B-myT"
generate(size=8)        # → "Uakgb_J5"
generate('0123456789abcdef', 16)  # custom alphabet + size

Node.js (CommonJS)

JavaScript
// 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
}

Domande Frequenti

NanoID è crittograficamente sicuro?
Sì — quando si usa l'import predefinito, NanoID genera ID usando il CSPRNG a livello OS (crypto.getRandomValues nei browser, crypto.randomFillSync in Node.js). Questa è la stessa fonte di entropia usata per la generazione di chiavi crittografiche. I valori NanoID sono adatti per token di sessione, chiavi API e altri identificatori sensibili alla sicurezza.
Posso usare NanoID come chiave primaria del database?
Sì. Le stringhe NanoID sono URL-safe e possono essere memorizzate come colonne CHAR o VARCHAR. Tuttavia, NanoID non ha un componente timestamp, quindi gli ID non sono ordinabili per ordine di generazione — questo causerà frammentazione degli indici B-tree ad alti tassi di inserimento, simile a UUID v4. Per chiavi primarie ordinate nel tempo, usare ULID o UUID v7.
Come si confronta NanoID con crypto.randomUUID()?
Entrambi usano un CSPRNG e forniscono forte casualità. crypto.randomUUID() è nativo (nessuna dipendenza), produce stringhe UUID v4 con trattini di 36 caratteri ed è universalmente riconosciuto da database e API. NanoID richiede un pacchetto npm ma produce stringhe più corte (21 chars predefinito) con un alfabeto personalizzabile. Per la maggior parte dei casi, preferire crypto.randomUUID() per evitare una dipendenza.
Cosa succede se si usa un NanoID molto corto?
Gli ID corti (es. 6-8 caratteri) hanno una probabilità di collisione significativamente più alta. Un NanoID di 6 caratteri dall'alfabeto predefinito di 64 chars ha solo ~68 miliardi di valori possibili — adatto per qualche migliaio di ID prima che il rischio di collisione diventi non trascurabile. Usare la tabella di probabilità di collisione sopra per scegliere una dimensione appropriata per il volume di ID atteso.
Posso usare NanoID in un browser senza npm?
Sì. NanoID supporta import ESM da CDN (es. jsDelivr o esm.sh). Importarlo come modulo in un tag script con type="module". Questo è utile per la prototipazione rapida ma non raccomandato per la produzione — fissare a una versione specifica e considerare di ospitare autonomamente lo script.
NanoID funziona in tutti gli ambienti?
NanoID funziona in tutti i browser moderni, Node.js, Deno, Bun, Cloudflare Workers e Vercel Edge Functions. Per React Native, è richiesto un polyfill per getRandomValues (react-native-get-random-values). La libreria è progettata per essere agnostica all'ambiente e rileva automaticamente l'API crypto disponibile.