最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

如何将uuid缩短并扩展为15个或更少的字符

运维笔记admin20浏览0评论

如何将uuid缩短并扩展为15个或更少的字符

如何将uuid缩短并扩展为15个或更少的字符

给定一个没有短划线的uuid(v4),如何将其缩短为15个或少于15个字符的字符串?我也应该能够从15个字符的字符串返回到原始的uuid。

我试图缩短它以将其发送到平面文件中,文件格式将此字段指定为15个字符的字母数字字段。鉴于缩短的uuid,我应该能够将它映射回原始的uuid。

这是我尝试过的,但绝对不是我想要的。

export function shortenUUID(uuidToShorten: string, length: number) {
  const uuidWithoutDashes = uuidToShorten.replace(/-/g , '');
  const radix = uuidWithoutDashes.length;
  const randomId = [];

  for (let i = 0; i < length; i++) {
    randomId[i] = uuidWithoutDashes[ 0 | Math.random() * radix];
  }
  return randomId.join('');
}
回答如下:

正如AuxTaco指出的那样,如果你实际上是指“字母数字”,因为它匹配“/ ^ [A-Za-z0-9] {0,15} /”(给出的位数为26 + 26 + 10 = 62)那真是不可能。你不能在一加仑桶中装入3加仑的水而不会丢失一些东西。 UUID是128位,因此要将其转换为62的字符空间,您至少需要22个字符(log[base 62](2^128) == ~22)。

如果你的charset更灵活,只需要15个unicode字符就可以放入文本文档,那么我的回答会有所帮助。


注意:这个答案的第一部分,我认为它的长度为16,而不是15.更简单的答案是行不通的。下面更复杂的版本仍然会。


为此,您需要使用某种双向压缩算法(类似于用于压缩文件的算法)。

但是,尝试压缩类似UUID的问题是你可能会遇到很多冲突。

UUID v4长度为32个字符(不带短划线)。它是十六进制的,所以它的字符空间是16个字符(0123456789ABCDEF

这给你一些可能的组合16^32,大约3.4028237e+38340,282,370,000,000,000,000,000,000,000,000,000,000。要使其在压缩后可恢复,您必须确保没有任何冲突(即,没有2个UUID变成相同的值)。这是很多可能的值(这正是我们为UUID使用那么多的原因,2个随机UUID的概率只是该数字大数的1)。

要将这么多可能性压缩到16个字符,你必须至少拥有尽可能多的可能值。有16个字符,你必须有256个字符(该大数字的根16,256^16 == 16 ^ 32`)。假设你有一个永远不会产生碰撞的算法。

确保永远不会发生冲突的一种方法是将其从base-16编号转换为base-256编号。这将给你一对一的关系,确保没有碰撞并使其完全可逆。通常,在JavaScript中切换基础很简单:parseInt(someStr, radix).toString(otherRadix)(例如,parseInt('00FF', 16).toString(20)。不幸的是,JavaScript只能达到36的基数,所以我们必须自己进行转换。

如此庞大的基地的捕获代表它。您可以随意选择256个不同的字符,将它们放入一个字符串中,然后将其用于手动转换。但是,我不认为标准美国键盘上有256个不同的符号,即使您将大写和小写视为不同的字形。

一个更简单的解决方案是使用0中的任意字符代码和255String.fromCharCode()

另一个小问题是,如果我们试图将所有这些都视为一个大数字,我们就会遇到问题,因为它是一个非常大的数字,JavaScript无法正确地表示它。

而不是那样,因为我们已经有了十六进制,我们可以将它分成几对小数,转换它们,然后将它们吐出来。 32个十六进制数字= 16对,因此(巧合)是完美的。 (如果您必须以任意大小解决此问题,则必须进行一些额外的数学运算并转换为将数字拆分为多个,转换,然后重新组合。)

const uuid = '1234567890ABCDEF1234567890ABCDEF';
const letters = uuid.match(/.{2}/g).map(pair => String.fromCharCode(parseInt(pair, 16)));
const str = letters.join('');
console.log(str);
发布评论

评论列表(0)

  1. 暂无评论