常见基础密码算法
UUID v4 生成
/**
* 生成 Nonce(UUID 格式,无连字符)
* @returns UUID 字符串
*/
export function generateNonce(): string {
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
- 先讲这串固定字符:
xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx
这是一个模板字符串,长度固定 32 位。 它的结构是 UUID v4 标准: x = 等待替换成随机十六进制字符 4 = 固定不变,代表 UUID 版本 4 y = 按规则替换成 8/9/a/b 其中一个 所以这串字符本身不会变,只是把里面的 x 和 y 替换掉。
- 核心:replace 函数到底在干嘛?
.replace(/[xy]/g, 回调函数)
replace 是字符串替换方法,在这里的作用: 扫描整个模板字符串 找到每一个 x 或 y 对每一个 x/y 单独执行一次回调函数 用回调函数返回的字符 替换掉原来的 x/y 简单说:replace 在这里 = 逐个替换 x 和 y
- /[xy]/g 是什么?(正则表达式)
这是全局匹配 x 或 y 的正则: [xy] = 匹配 x 或者 y 任意一个字符 g = global(全局匹配),意思是不要只替换第一个,要替换所有匹配到的 所以:/[xy]/g = 找到模板里所有的 x 和 y,一个都不放过
-
Math.random() 生成一个 0 ≤ 数 < 1 的随机小数 例子:0.123、0.987
-
* 16 把随机小数放大 16 倍 结果变成:0 ≤ 数 < 16 例子:1.968、15.792
-
| 0 按位或 0,作用就是:取整数,直接砍掉小数 不是四舍五入,是直接丢小数点后面的数 例子: 1.968 → 1 15.792 → 15
-
const v = c === ‘x’ ? r : (r & 0x3) | 0x8;
作用:判断当前是替换 x 还是 y
如果是 x → 直接用随机数 r 如果是 y → 强制改成 8、9、a、b 其中一个 拆成两部分看:
① c === ‘x’ ? r
c 就是当前要替换的字符(x 或 y) 如果是 x,直接返回刚才的随机数 r 范围:0 ~ 15 ② : (r & 0x3) | 0x8
这是 UUID v4 标准规则,专门处理 y 我用最简单的方式解释: r & 0x3 只保留最后 2 位二进制 结果一定是:0、1、2、3 | 0x8 把数字加上 8 0+8=8 1+8=9 2+8=10 3+8=11 最终 y 只能是:
8、9、10、11 这四个数!
扩展知识点
uuid 版本知识
# UUID 1~5 版本快速说明
## UUID v1
- **基于:时间戳 + MAC 地址**
- 特点:
- 按时间顺序生成
- 全球唯一
- **可以反推出生成时间 + 设备 MAC**
- 适用:需要有序、可追溯、内部系统
- 安全:弱(会暴露设备信息)
- 版本位:`1`
## UUID v2
- **基于:时间戳 + MAC + 账号ID(POSIX UID/GID)**
- 特点:v1 的变种,极少用
- 适用:DCE 安全环境(几乎见不到)
- 版本位:`2`
## UUID v3
- **基于:命名空间 + 字符串 → MD5 哈希**
- 特点:
- 相同输入 → 相同 UUID
- 固定、可重复生成
- 安全:MD5 已不算安全
- 适用:需要根据名字稳定生成 ID
- 版本位:`3`
## UUID v4
- **基于:纯随机数**
- 特点:
- 完全随机
- 不依赖时间、MAC、任何信息
- 最常用、最安全
- 适用:token、nonce、唯一标识、防重放
- 版本位:`4`
- 你前面那段代码生成的就是 **v4**
## UUID v5
- **基于:命名空间 + 字符串 → SHA-1 哈希**
- 特点:
- 和 v3 逻辑一样,但哈希更安全(SHA-1)
- 相同输入 → 相同 UUID
- 适用:需要稳定、安全、可重复生成的 ID
- 版本位:`5`
---
# 超简记忆版
- **v1:时间+MAC,有序,可追踪**
- **v2:v1变种,几乎不用**
- **v3:MD5哈希,固定重复**
- **v4:纯随机,最常用最安全**
- **v5:SHA1哈希,安全固定重复**
---
# 一眼识别版本(最重要)
UUID 格式:
`xxxxxxxx-xxxx-Vxxx-xxxx-xxxxxxxxxxxx`
看**第三个分段的第一个字符**就是版本:
- `1xxxx` → v1
- `2xxxx` → v2
- `3xxxx` → v3
- `4xxxx` → v4
- `5xxxx` → v5
需要我再给你对比一下**v1 和 v4 到底该用哪个、安全性差在哪**吗?