生成随机 uuid Javascript

新手上路,请多包涵

我正在尝试构建一个函数来生成随机 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);

原文由 547n00n 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 522
2 个回答

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

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

原文由 Aaron Plocharczyk 发布,翻译遵循 CC BY-SA 4.0 许可协议

确实,您的方法生成了一个或多或少的随机字符串,可以用作 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]
  • 通过使用带零的按位 OR 运算符 ( | 0 ),我们基本上将结果置底,因为数字被转换为整数。 (包含 0 - 包含 15)[例如:5] 无需过多讨论逻辑运算的细节,按位或零表示没有位发生变化。但是,由于按位运算适用于 32 位整数,因此结果被强制转换为整数。在没有太多性能开销的情况下,我们可以用专用的 floor 函数替换此操作以提高可读性。 ( 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 和按位或运算符与 0x8 一起使用,结果( v 的值将是 5db 中的任何一个) ,10,11。
  • 旁注:这种情况永远不会发生在您的方法中,因为被替换的字符串仅包含 x 值。

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

tldr :给我 一个在 typescript 中返回 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);
  });
}

原文由 Daniel Metzner 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题