生产唯一的字符串ID 之 nanoid

前言

编程的世界里,在很多的时候,我们都需要一个唯一的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压缩,还是回到前面所说的库的优点,小。

到此,本文就结束了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容