JS 生成 UUID:crypto.randomUUID 与 uuid npm 包

crypto.randomUUID(现代标准方案)

浏览器和 Node.js 都内置支持:

const id = crypto.randomUUID();
console.log(id);
// "3f6c2a6f-8d7d-4f9c-b7d5-3fcb52c8a1aa"

这是 UUID v4(随机),格式固定为 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx

  • Chrome / Edge / Firefox 均支持
  • Node.js ≥ 19 直接用全局 crypto;Node.js 15–18 从 crypto 模块导入
// Node.js 15-18
const { randomUUID } = require('crypto');
console.log(randomUUID());

uuid npm 包

适合需要 v1 / v5 或更好兼容性的场景:

npm install uuid
import { v4 as uuidv4 } from 'uuid';

console.log(uuidv4());
// "110e8400-e29b-41d4-a716-446655440000"

各版本:

版本特点场景
v1时间 + MAC 地址需要可排序的 ID
v4全随机最常用,通用唯一 ID
v5命名空间 + hash相同输入生成相同 ID

老版本兼容写法

不能用 crypto.randomUUID 时的回退:

function uuid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
    .replace(/[xy]/g, c => {
      const r = Math.random() * 16 | 0;
      const v = c === 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
    });
}

Math.random() 不是密码学安全随机数,高并发下理论上存在碰撞风险,生产环境优先用 crypto.randomUUID()

短 ID(不是 UUID)

只需要一个不太长的唯一标识,不要求标准格式时:

const id = Math.random().toString(36).slice(2);
// "k9x2m8q"

toString(36) 用 0–9 + a–z 36进制,slice(2) 去掉开头的 0.。这个不是 UUID,不保证唯一性,只适合临时标识(如 DOM id、session key)。

更长更安全的短 ID:

const id = crypto.getRandomValues(new Uint8Array(8))
  .reduce((acc, b) => acc + b.toString(16).padStart(2, '0'), '');
// "a3f2c1d9e4b70821"

使用场景

  • 数据库主键:用 UUID v4,全随机防枚举
  • 请求追踪X-Request-ID header 用 crypto.randomUUID()
  • 前端元素 key:用短 ID 即可
  • 内容寻址:用 UUID v5,同 URL 生成相同 ID