Trình tạo NanoID
Tạo ID duy nhất nhỏ gọn, an toàn với URL và bảng chữ cái tùy chỉnh
Bảng chữ cái
Kích thước
Số lượng
Nhấn Tạo để tạo NanoID
NanoID là gì?
NanoID là bộ tạo ID ngẫu nhiên nhỏ, nhanh, URL-safe. Theo mặc định nó tạo ra các chuỗi 21 ký tự sử dụng bảng chữ cái 64 ký tự (A-Za-z0-9_-), cung cấp khoảng 126 bit entropy.
NanoID không nhúng timestamp hay bất kỳ dữ liệu có cấu trúc nào. Mỗi ID hoàn toàn ngẫu nhiên, được tạo từ cryptographically secure random number generator của hệ điều hành.
NanoID so với UUID v4
NanoID và UUID v4 đều là bộ tạo ID ngẫu nhiên được hỗ trợ bởi CSPRNG. Chúng khác nhau về định dạng, độ dài và hỗ trợ hệ sinh thái:
| Thuộc tính | NanoID (mặc định) | UUID v4 |
|---|---|---|
| Định dạng | Chữ số URL-safe + _- | Hex thập lục phân có gạch nối |
| Độ dài | 21 ký tự (mặc định) | 36 ký tự |
| Entropy | ~126 bit | 122 bit |
| URL-safe | Có — không cần mã hóa | Có (với dấu gạch nối) |
| Bảng chữ cái | 64 ký tự (A-Za-z0-9_-) | 16 ký tự (0-9a-f) |
| Phụ thuộc | Yêu cầu gói npm | Gốc (crypto.randomUUID) |
| Có thể Tùy chỉnh | Có — độ dài và bảng chữ cái | Không |
| Tiêu chuẩn | Không có (thư viện cộng đồng) | RFC 4122 / RFC 9562 |
Chọn UUID v4 khi khả năng tương tác với các hệ thống bên ngoài quan trọng. Chọn NanoID khi bạn muốn ID ngắn hơn.
Xác suất Va chạm theo Kích thước
Xác suất va chạm của NanoID phụ thuộc vào độ dài ID và tốc độ tạo. Bảng sau sử dụng bảng chữ cái 64 ký tự mặc định:
| Kích thước (ký tự) | ID có thể có | Độ an toàn va chạm |
|---|---|---|
| 6 | 64 | ~1 trong 4,5 tỷ — an toàn cho vài nghìn ID |
| 8 | 64 | ~1 trong 4,5 nghìn tỷ — an toàn cho hàng triệu ID |
| 11 | 64 | ~1 trong 2,8 triệu tỷ — an toàn cho hàng tỷ ID |
| 16 | 64 | ~1 trong 1,2 × 10^19 — an toàn cho hàng nghìn tỷ ID |
| 21 | 64 | ~1 trong 10^30 — an toàn cho 100 tỷ ID mỗi ngày trong nhiều thế kỷ |
| 32 | 64 | So sánh với UUID v4 (122 bit) |
| 36 | 36 | Vượt qua UUID v4 |
Kích thước 21 ký tự mặc định được chọn để phù hợp với khả năng kháng va chạm của UUID v4 (~126 bit) trong khi ngắn hơn 41%.
Bảng chữ cái Tùy chỉnh
Bảng chữ cái của NanoID hoàn toàn có thể tùy chỉnh. Thư viện chấp nhận bất kỳ chuỗi ký tự duy nhất nào làm bảng chữ cái:
A-Za-z0-9_-A-Za-z0-90-9a-f0-9Quan trọng: chỉ sử dụng nanoid/non-secure cho các ứng dụng không nhạy cảm về bảo mật. Đối với bất kỳ ID nào cần không thể đoán được, luôn sử dụng import an toàn mặc định.
Cách NanoID Tạo ra Ngẫu nhiên
NanoID sử dụng cryptographically secure pseudo-random number generator (CSPRNG) của hệ điều hành. Trong trình duyệt đây là crypto.getRandomValues(); trong Node.js là crypto.randomFillSync().
Rejection Sampling (Tránh Modulo Bias)
Cách tiếp cận đơn giản để tạo ký tự ngẫu nhiên là: lấy một byte ngẫu nhiên (0–255) và tính byte % alphabetSize. Điều này tạo ra modulo bias.
NanoID loại bỏ bias này bằng cách sử dụng rejection sampling:
- Xác định mask power-of-two nhỏ nhất bao phủ kích thước bảng chữ cái
- Tạo các byte ngẫu nhiên và áp dụng mask:
byte & mask - Nếu giá trị được mask nằm trong phạm vi bảng chữ cái, hãy sử dụng. Nếu không, loại bỏ và thử lại.
Điều này có nghĩa là một số byte ngẫu nhiên bị loại bỏ, nhưng kết quả là phân phối hoàn toàn đồng đều trên bảng chữ cái.
// 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"Hỗ trợ Môi trường
Ví dụ Mã
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"Trình duyệt (CDN)
NanoID có thể được sử dụng trực tiếp trong trình duyệt thông qua import CDN. Không cần bước build cho tạo mẫu nhanh.
// 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
}