前言
编程的世界里,在很多的时候,我们都需要一个唯一的ID来代表一些数据(事物)是唯一的!也许很多人都知道UUID,很多项目都会使用UUID来做唯一的标识。今天这篇文章记录的就是生成唯一ID库nanoid
优点
在学习一个东西的时候,我们一般都会先了解他的优缺点,学习和使用后可以给我带来什么便利以及会损失什么。那么,让我们来了解一下吧!
- 小:压缩后只有108字节,没有依赖性
- 快:比UUID快60%
- 安全:使用随机加密,安全。可以在集群中使用
- 可移植性:可以在14种语言中运行
使用方法
image.png
很简单
- 执行yarn add nanoid
- 引入 import { nanoid } from 'nanoid' 或者 const { nanoid } = require('nanoid')
- 使用 nanoid(20) 传的参数是生产ID的长度,不指定默认长度为21
源码
image.png
项目目录
image.png
可以看到,没有依赖任何库
image.png
生成ID的字母表
import crypto from 'crypto'
import { urlAlphabet } from './url-alphabet/index.js'
const POOL_SIZE_MULTIPLIER = 32 //缓冲池
let pool, poolOffset
let random = bytes => {
if (!pool || pool.length < bytes) {
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
crypto.randomFillSync(pool)
poolOffset = 0
} else if (poolOffset + bytes > pool.length) {
crypto.randomFillSync(pool)
poolOffset = 0
}
let res = pool.subarray(poolOffset, poolOffset + bytes)
poolOffset += bytes
return res
}
let customRandom = (alphabet, size, getRandom) => {
// 生成ID需要的位掩码
let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
// 一步要生成的随机字节的大小
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = getRandom(step)
let i = step
while (i--) {
// 拒绝超过字母表大小的随机字节 比如不能生成字母表以外的字符
id += alphabet[bytes[i] & mask] || ''
if (id.length === size) return id
}
}
}
}
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
let nanoid = (size = 21) => {
let bytes = random(size)
let id = ''
while (size--) {
// 位掩码将字节修剪到字母表大小
id += urlAlphabet[bytes[size] & 63]
}
return id
}
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
这是源代码,是的,你没有看错,源代码只有这么多!只有这呢多,再经过Gzip压缩,还是回到前面所说的库的优点,小。
到此,本文就结束了。