生成随机的uuid Javascript

时间:2019-12-19 15:23:23

标签: javascript math random uuid

我正在尝试构建一个函数来生成随机的uuid,我在堆栈上发现了一些东西,我需要稍微了解一下该函数如何使用Typescript创建它:

public generateUniqSerial() {
    return 'xxxx-xxxx-xxx-xxxx'.replace(/[x]/g, function (c) {
      var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
    });
  }

在es6中写得很好,您能否帮助您理解该行的工作方式:

* var r = Math.random()* 16 | 0,v = c =='x'? r:(r&0x3 | 0x8); *

2 个答案:

答案 0 :(得分:1)

您的方法确实会生成或多或少的随机字符串,可以用作uuid。但是,它的可读性很差,换来的代码很短。此外,它不符合UUIDS的RFC标准。有关功能更新的解决方案,请查看:https://stackoverflow.com/a/2117523/8524465以及有关UUIDS的更多详细信息:https://stackoverflow.com/a/105074/8524465

但是,让我们重点关注您所请求的行,让我尝试逐步解释它。

var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);

此行定义2个变量,即rv。我们可以轻松地将其分为两行。

var r = Math.random() * 16 | 0;
var v = c == 'x' ? r : (r & 0x3 | 0x8);

变量定义1:(r = Math.random() * 16 | 0;):

  • Math.random()是一个返回介于01之间的值的函数。 (包括0个-排除1个)[例如:0.36342115]
  • 通过将值乘以16,结果在016之间。 (包括0-排除16)[例如:5.8147384]
  • 通过使用具有零(| 0)的按位OR运算符,由于将数字ist强制转换为整数,因此我们基本上对结果进行求底。 (包括0-包括15)[例如:5] 无需过多讨论逻辑运算,按位或零表示没有位被更改。但是,由于按位运算是对32位整数进行的,因此结果会被强制转换并最终取整为整数。没有太多的性能开销,我们可以用专用的发言权功能代替此操作以提高可读性。 (https://stackoverflow.com/a/7488075/8524465

除无符号右移>>>以外的所有按位运算 有符号的32位整数。因此,使用按位运算将转换 浮动为整数。

var r = Math.floor(Math.random() * 16);

变量定义2(var v = c == 'x' ? r : (r & 0x3 | 0x8);):

  • 此处使用三元运算符来使所需的代码简短,以缩短分配时间。
    var (variableName) = (condition) ? (valueIfConditionIsTrue) : (valueIfConditionIsFalse);
    
    可以使用简单的if/else-statement来重写。
    var v = "";
    if (c === 'x') { 
        v = r;
    }
    else {
        v = r & 0x3 | 0x8;
    }
    

变量定义2.1(var v = r & 0x3 | 0x8):

  • 我们知道r的值为0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,or 15
  • 通过将0x3与按位AND运算符和0x8与按位OR运算符一起使用,结果(v)的值为8,9,10, 11。
  • 旁注:这种情况永远不会在您的方法中发生,因为被替换的字符串仅包含x值。

有关按位运算的更多信息,请查看:https://www.w3schools.com/js/js_bitwise.asp

tldr :只需给我一种以打字稿返回UUID的方法

使用@broofa的最新版本(https://stackoverflow.com/a/2117523/8524465)作为基础:

uuidv4(): string {  
    // @ts-ignore  
    return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>  
        // tslint:disable-next-line:no-bitwise  
        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)  
    );
}

完成操作:您的方法已简化并用打字稿写成

generateUniqSerial(): string {  
    return 'xxxx-xxxx-xxx-xxxx'.replace(/[x]/g, (c) => {  
        const r = Math.floor(Math.random() * 16);  
        return r.toString(16);  
  });  
}

答案 1 :(得分:0)

它将'x'中的每个'xxxx-xxxx-xxx-xxxx'替换为随机的[0123456789abcdef]十六进制字符。比您真正需要做的多一点。我通常这样做:

Math.random().toString().replace("0.", "")