Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将uuid缩短和扩展到15个或更少的字符_Javascript_Node.js_Typescript - Fatal编程技术网

Javascript 如何将uuid缩短和扩展到15个或更少的字符

Javascript 如何将uuid缩短和扩展到15个或更少的字符,javascript,node.js,typescript,Javascript,Node.js,Typescript,给定一个没有破折号的uuid(v4),如何将其缩短为15个或少于15个字符的字符串?我还应该能够从15个字符的字符串返回到原始uuid 我试图缩短它以平面文件的形式发送,文件格式将此字段指定为15个字符的字母数字字段。考虑到缩短的uuid,我应该能够将其映射回原始uuid 这是我尝试过的,但绝对不是我想要的 export function shortenUUID(uuidToShorten: string, length: number) { const uuidWithoutDashes

给定一个没有破折号的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('');
}
导出函数shortenuid(uuidthorten:string,长度:number){
const uuidthout破折号=uuidthorten.replace(/-/g');
常量基数=uuid不带破折号.length;
常量randomId=[];
for(设i=0;i
正如AuxTaco指出的,如果你实际上指的是“字母数字”,因为它匹配“/^[A-Za-z0-9]{0,15}/”(给出26+26+10=62的位数),那么这真的是不可能的。你不可能在一个加仑桶里装3加仑的水而不损失一些东西。UUID是128位,因此要将其转换为62个字符空间,至少需要22个字符(
log[base 62](2^128)
==22)

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


注意:这个答案的第一部分,我想它说的长度是16,而不是15。简单的答案行不通。下面更复杂的版本仍将继续


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

然而,试图压缩UUID之类的东西的问题是,可能会有很多冲突

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

这为您提供了许多可能的
16^32
,大约为
3.4028237e+38
34028237000000000000000000000000000
。要使其在压缩后可恢复,必须确保没有任何冲突(即,没有两个UUID变成相同的值)。这是很多可能的值(这正是为什么我们对UUID使用那么多,2个随机UUID的概率仅为该数字中的1)

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

确保不会发生冲突的一种方法是将其从base-16数字转换为base-256数字。这将给你一个1对1的关系,确保没有碰撞,并使其完全可逆。通常情况下,在JavaScript中切换基数很容易:
parseInt(someStr,radix)。toString(otherRadix)
(例如,
parseInt('00FF',16)。toString(20)
。不幸的是,JavaScript的基数最多只有36,所以我们必须自己进行转换

有这么大的基数的catch就代表了它。你可以任意选择256个不同的字符,将它们放入一个字符串中,然后使用它进行手动转换。然而,我认为标准的美国键盘上没有256个不同的符号,即使你将大小写视为不同的glyph

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

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

取而代之的是,既然我们已经有了十六进制,我们可以把它分成几对小数,转换它们,然后把它们吐出来。32个十六进制数字=16对,所以(巧合的)这将是完美的。(如果你必须解决任意大小的问题,你必须做一些额外的数学运算和转换,将数字分成几部分,转换,然后重新组装。)

const uuid='1234567890ABCDEF1234567890ABCDEF';
const letters=uuid.match(/.{2}/g).map(pair=>String.fromCharCode(parseInt(pair,16));
const str=字母连接(“”);

console.log(str);
你已经尝试了什么?对不起,我的错。我应该添加我正在做的。这完全没有用,因此没有添加。我真的不明白你在尝试做什么。你的算法是不确定的(即,
Math.random()
),所以每次运行
shortenuid()
在同一个输入UUID上,您将生成一个不同的缩短版本。您希望如何以这种方式进行反向映射?缩短UUID的最终目的是什么?您的问题可能有一个完全不同的解决方案。这正是我的观点,也是我提到的原因,我所做的是无用的。@msinfo我正试图将其缩短为以平面文件的形式发送,文件格式将此字段指定为15个字符的字母数字字段。给定缩短的uuid,我应该能够将其映射回原始uuid。存在一些问题。这不适用于表示单个数字十六进制数的对:请尝试
uuid='0102030405060708010203405060708';
。如果UUID包含
00
,您要发送到的系统可能会在“15个字符的字母数字字段”中的U+0000 NULL处停止。这压缩到16个字符,而不是15个。哎呀,出于某种原因,我以为它是16个。实际上,我用了一种更复杂的方法更新了我的答案,这种方法适用于任意字符集和长度,因此可以用于更小的字符。你也可以过滤掉任何有问题的字符。不确定为什么你认为它不适用于十六进制表示单个数字,而不是