一个生成4种UUID的Typescript代码(不依赖任何库)

最近写个uni-app前端,由于要兼容小程序环境,标准几个npm里的库都不能用了。看了下网上的uuid js库,再加上short-uuid的源码。一并输入GPT敲打了几个来回后,得到这样的代码:

uuid.ts

enum UUIDFormat {
  CookieBase90,
  FlickrBase58,
  UUID25Base36
}

const constants = {
  [UUIDFormat.CookieBase90]:
    "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+-./:<=>?@[]^_`{|}~",
  [UUIDFormat.FlickrBase58]: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ',
  [UUIDFormat.UUID25Base36]: '0123456789abcdefghijklmnopqrstuvwxyz'
}

/**
 * Calculate length for the shortened ID
 * @param {number} alphabetLength
 * @returns {number}
 */
const getShortIdLength = (alphabetLength: number): number =>
  Math.ceil(Math.log2(Math.pow(2, 128)) / Math.log2(alphabetLength))

/**
 * Convert a hex string to a custom base string
 * @param {string} hex
 * @param {string} alphabet
 * @returns {string}
 */
const hexToCustomBase = (hex: string, alphabet: string): string => {
  const base = alphabet.length
  let num = BigInt(`0x${hex}`)
  let encoded = ''

  while (num > 0) {
    encoded = alphabet[Number(num % BigInt(base))] + encoded
    num = num / BigInt(base)
  }

  return encoded
}

interface PaddingParams {
  shortIdLength: number
  consistentLength: boolean
  paddingChar: string
}

/**
 * Takes a UUID, strips the dashes, and translates to custom base
 * @param {string} longId
 * @param {string} alphabet
 * @param {PaddingParams} [paddingParams]
 * @returns {string}
 */
const shortenUUID = (longId: string, alphabet: string, paddingParams?: PaddingParams): string => {
  const hex = longId.replace(/-/g, '')
  const translated = hexToCustomBase(hex, alphabet)

  if (!paddingParams || !paddingParams.consistentLength) return translated

  return translated.padStart(paddingParams.shortIdLength, paddingParams.paddingChar)
}

/**
 * Generate a standard UUID
 * @returns {string}
 */
const generateUUID = (): string => {
  const hexDigits = '0123456789abcdef'
  const s: string[] = Array(36).fill('')

  for (let i = 0; i < 36; i++) {
    s[i] = hexDigits.charAt(Math.floor(Math.random() * 0x10))
  }
  s[14] = '4'
  s[19] = hexDigits.charAt((parseInt(s[19], 16) & 0x3) | 0x8)
  s[8] = s[13] = s[18] = s[23] = '-'

  return s.join('')
}

/**
 * Generate a UUID in either standard or short format based on the provided format
 * @param {UUIDFormat} [format] - Enum to specify the desired format
 * @returns {string}
 */
const uuid = (format?: UUIDFormat): string => {
  const standardUUID = generateUUID()
  if (format === undefined) {
    return standardUUID
  }

  const useAlphabet = constants[format]
  const shortIdLength = getShortIdLength(useAlphabet.length)

  const paddingParams: PaddingParams = {
    shortIdLength,
    consistentLength: true,
    paddingChar: useAlphabet[0]
  }

  return shortenUUID(standardUUID, useAlphabet, paddingParams)
}

export { uuid, UUIDFormat }

测试:

console.log(uuid()) // 原版

console.log(uuid(UUIDFormat.CookieBase90)) // 可打印字符集版(20字符)

console.log(uuid(UUIDFormat.FlickrBase58)) //大小写压缩版(22字符)

console.log(uuid(UUIDFormat.UUID25Base36)) //小写数字压缩版(25字符)

输出:

fe6eee2b-f3bb-4afb-b6d1-427829aa2720
otDc4[?2Wo5JYd*F=AME
fV8nBAawjXG9dfQJvnmx6w
d4vid4vf6usa9bga6awv0jjja

奈斯~,通用4个场景

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值