前言
編程的世界里,在很多的時候,我們都需要一個唯一的ID來代表一些數(shù)據(jù)(事物)是唯一的!也許很多人都知道UUID,很多項目都會使用UUID來做唯一的標(biāo)識。今天這篇文章記錄的就是生成唯一ID庫nanoid
優(yōu)點
在學(xué)習(xí)一個東西的時候,我們一般都會先了解他的優(yōu)缺點,學(xué)習(xí)和使用后可以給我?guī)硎裁幢憷约皶p失什么。那么,讓我們來了解一下吧!
- ?。簤嚎s后只有108字節(jié),沒有依賴性
- 快:比UUID快60%
- 安全:使用隨機(jī)加密,安全。可以在集群中使用
- 可移植性:可以在14種語言中運行
使用方法

image.png
很簡單
- 執(zhí)行yarn add nanoid
- 引入 import { nanoid } from 'nanoid' 或者 const { nanoid } = require('nanoid')
- 使用 nanoid(20) 傳的參數(shù)是生產(chǎn)ID的長度,不指定默認(rèn)長度為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
// 一步要生成的隨機(jī)字節(jié)的大小
let step = Math.ceil((1.6 * mask * size) / alphabet.length)
return () => {
let id = ''
while (true) {
let bytes = getRandom(step)
let i = step
while (i--) {
// 拒絕超過字母表大小的隨機(jī)字節(jié) 比如不能生成字母表以外的字符
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--) {
// 位掩碼將字節(jié)修剪到字母表大小
id += urlAlphabet[bytes[size] & 63]
}
return id
}
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
這是源代碼,是的,你沒有看錯,源代碼只有這么多!只有這呢多,再經(jīng)過Gzip壓縮,還是回到前面所說的庫的優(yōu)點,小。
到此,本文就結(jié)束了。

