NanoID Generator
Generate tiny URL-safe unique IDs with customizable alphabet
Alfabet
Storlek
Antal
Klicka på Generera för att skapa NanoIDs
Vad är NanoID?
NanoID är en liten, snabb, URL-säker slumpmässig ID-generator. Som standard producerar den 21-teckens strängar med ett 64-teckens alfabet (A-Za-z0-9_-), vilket ger ungefär 126 bitar entropi — jämförbart med UUID v4:s 122 bitar men i en kortare sträng.
NanoID bäddar inte in en tidsstämpel eller några strukturerade data. Varje ID är rent slumpmässigt, genererat från operativsystemets kryptografiskt säkra slumptalsalgoritm (crypto.getRandomValues() i webbläsare, crypto.randomBytes() i Node.js).
NanoID vs UUID v4
NanoID och UUID v4 är båda slumpmässiga ID-generatorer som stöds av en CSPRNG. De skiljer sig i format, längd och ekosystemstöd:
| Egenskap | NanoID (standard) | UUID v4 |
|---|---|---|
| Format | URL-säker alfanumerisk + _- | Bindestreck-hexadecimalt |
| Längd | 21 tecken (standard) | 36 tecken |
| Entropi | ~126 bitar | 122 bitar |
| URL-säker | Ja — ingen kodning behövs | Ja (med bindestreck) |
| Alfabet | 64 tecken (A-Za-z0-9_-) | 16 tecken (0-9a-f) |
| Beroenden | Kräver npm-paket | Inbyggd (crypto.randomUUID) |
| Anpassningsbar | Ja — längd och alfabet | Nej |
| Standard | Ingen (gemenskapsbibliotek) | RFC 4122 / RFC 9562 |
Välj UUID v4 när interoperabilitet med externa system spelar roll — databaser med inbyggda UUID-kolumner, API:er som förväntar sig UUID-format eller loggningsinfrastruktur som tolkar UUID:n. Välj NanoID när du vill ha kortare ID:n och kontrollerar hela stacken.
Kollisionssannolikhet efter storlek
NanoID:s kollisionssannolikhet beror på ID-längden och genereringshastigheten. Följande tabell använder standard 64-teckens alfabet:
| Storlek (tecken) | Möjliga ID:n | Kollisionssäkerhet |
|---|---|---|
| 6 | 64 | ~1 på 4,5B — säker för några tusen ID:n |
| 8 | 64 | ~1 på 4,5B — säker för miljoner ID:n |
| 11 | 64 | ~1 på 2,8 kvadriljoner — säker för miljarder ID:n |
| 16 | 64 | ~1 på 1,2 × 10^19 — säker för biljoner ID:n |
| 21 | 64 | ~1 på 10^30 — säker för 100 miljarder ID:n per dag i århundraden |
| 32 | 64 | Jämförbar med UUID v4 (122 bitar) |
| 36 | 36 | Överstiger UUID v4 |
Standardstorleken 21 tecken är vald för att matcha UUID v4:s kollisionsresistens (~126 bitar) samtidigt som den är 41% kortare. För de flesta applikationer är 21 tecken rätt val.
Anpassade alfabet
NanoID:s alfabet är helt anpassningsbart. Biblioteket accepterar valfri sträng med unika tecken som alfabet och genererar ID:n med bara dessa tecken:
A-Za-z0-9_-A-Za-z0-90-9a-f0-9Viktigt: använd nanoid/non-secure bara för icke-säkerhetskänsliga applikationer (t.ex. UI-element-ID:n). För alla ID:n som behöver vara omöjliga att gissa, använd alltid standard säker import.
Hur NanoID genererar slumpmässighet
NanoID använder operativsystemets kryptografiskt säkra pseudoslumpmässiga nummergenerator (CSPRNG). I webbläsare är detta crypto.getRandomValues(); i Node.js är det crypto.randomFillSync(). Det är samma entropikälla som används för TLS-sessionsnycklar — mycket starkare än Math.random().
Avvisningssampling (undvika modulobias)
En naiv metod för att generera slumpmässiga tecken skulle vara: ta en slumpmässig byte (0–255) och beräkna byte % alphabetSize. Det introducerar modulobias — vissa tecken förekommer något oftare än andra när alfabet storleken inte jämnt delar 256.
NanoID eliminerar denna bias med avvisningssampling:
- Bestäm den minsta tvåpotensmasken som täcker alfabetstorleken (t.ex. för ett 64-teckens alfabet är masken 63 = 0b00111111)
- Generera slumpmässiga bytes och applicera masken:
byte & mask - Om det maskerade värdet är inom alfabetets intervall, använd det. Annars, kassera och försök igen.
Det innebär att vissa slumpmässiga bytes kasseras, men resultatet är en perfekt jämn fördelning över alfabetet — inget tecken är mer sannolikt än något annat.
// 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"Miljöstöd
Kodexempel
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"Webbläsare (CDN)
NanoID kan användas direkt i webbläsaren via en CDN-import. Inget byggsteg krävs för snabb prototypframtagning.
// 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
}