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ínhNanoID (mặc định)UUID v4
Định dạngChữ số URL-safe + _-Hex thập lục phân có gạch nối
Độ dài21 ký tự (mặc định)36 ký tự
Entropy~126 bit122 bit
URL-safeCó — không cần mã hóaCó (với dấu gạch nối)
Bảng chữ cái64 ký tự (A-Za-z0-9_-)16 ký tự (0-9a-f)
Phụ thuộcYêu cầu gói npmGốc (crypto.randomUUID)
Có thể Tùy chỉnhCó — độ dài và bảng chữ cáiKhông
Tiêu chuẩnKhô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
664~1 trong 4,5 tỷ — an toàn cho vài nghìn ID
864~1 trong 4,5 nghìn tỷ — an toàn cho hàng triệu ID
1164~1 trong 2,8 triệu tỷ — an toàn cho hàng tỷ ID
1664~1 trong 1,2 × 10^19 — an toàn cho hàng nghìn tỷ ID
2164~1 trong 10^30 — an toàn cho 100 tỷ ID mỗi ngày trong nhiều thế kỷ
3264So sánh với UUID v4 (122 bit)
3636Vượ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:

Chỉ sốA-Za-z0-9_-
Sử dụng '0123456789' cho ID tất cả chữ số — hữu ích cho mã SMS hoặc định danh kiểu PIN.
Hex chữ thườngA-Za-z0-9
Sử dụng '0123456789abcdef' cho chuỗi hex nhỏ gọn không có định dạng gạch nối UUID.
Dễ đọc với con người0-9a-f
Loại trừ các ký tự mơ hồ về mặt hình ảnh (0, O, 1, I, l) cho các ID mà người dùng có thể cần nhập thủ công.
Miền tùy chỉnh0-9
Sử dụng bất kỳ tập ký tự nào phù hợp với ứng dụng của bạn — ví dụ chỉ nguyên âm+phụ âm cho ID có thể đọc được.

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

  1. Xác định mask power-of-two nhỏ nhất bao phủ kích thước bảng chữ cái
  2. Tạo các byte ngẫu nhiên và áp dụng mask: byte & mask
  3. 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.

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"

Hỗ trợ Môi trường

Browser
Trình duyệt hiện đại (Chrome 37+, Firefox 34+, Safari 7+) — sử dụng crypto.getRandomValues()
Node.js 14+
Node.js 14.18+ — sử dụng crypto.randomFillSync()
Deno
Deno — sử dụng crypto.getRandomValues()
Bun
React Native — yêu cầu polyfill expo-crypto hoặc react-native-get-random-values
Edge / Cloudflare Workers
Edge runtimes (Cloudflare Workers, Vercel Edge) — Web Crypto API có sẵn
React Native
Bun — hỗ trợ crypto gốc

Ví dụ Mã

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"

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.

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
}

Câu hỏi Thường gặp

NanoID có an toàn về mặt mật mã không?
Có — khi sử dụng import mặc định, NanoID tạo ID sử dụng CSPRNG cấp độ OS.
Tôi có thể sử dụng NanoID làm khóa chính database không?
Có. Chuỗi NanoID URL-safe và có thể được lưu dưới dạng cột CHAR hoặc VARCHAR.
NanoID so sánh với crypto.randomUUID() như thế nào?
Cả hai đều sử dụng CSPRNG. crypto.randomUUID() là gốc (không có phụ thuộc), tạo ra các chuỗi UUID v4 36 ký tự có gạch nối.
Điều gì xảy ra nếu tôi sử dụng NanoID rất ngắn?
Các ID ngắn (ví dụ 6–8 ký tự) có xác suất va chạm cao hơn đáng kể.
Tôi có thể sử dụng NanoID trong trình duyệt mà không có npm không?
Có. NanoID hỗ trợ import ESM từ CDN (ví dụ jsDelivr hoặc esm.sh).
NanoID có hoạt động trong tất cả môi trường không?
NanoID hoạt động trong tất cả các trình duyệt hiện đại, Node.js, Deno, Bun, Cloudflare Workers và Vercel Edge Functions.