生成随机 uuid Javascript
generate Random 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);*
它只是用一个随机的 [0123456789abcdef] 十六进制字符替换 'xxxx-xxxx-xxx-xxxx'
中的每个 'x'
。比你真正需要为 uuid 做的多一点。我通常这样做:
Math.random().toString().replace("0.", "")
你的方法确实生成了一个或多或少的随机字符串,可以用作 uuid。但是,它的可读性很差,换来的是非常短小的代码。此外,它不遵守 UUIDS 的 RFC 标准。如需函数的更新解决方案,请查看: and for more details on UUIDS:
但是,让我们特别关注您请求的行,让我尝试逐步解释它。
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
这一行定义了2个变量,分别是r
和v
。我们可以轻松地将其分成两行。
var r = Math.random() * 16 | 0;
var v = c == 'x' ? r : (r & 0x3 | 0x8);
变量定义 1:(r = Math.random() * 16 | 0;
):
Math.random()
是 returns 介于 0
和 1
之间的一个函数。 (0 包含 - 1 不包含)[例如:0.36342115]
- 将该值乘以 16,结果介于
0
和 16
之间。 (包含 0 - 不包含 16)[例如:5.8147384]
- 通过使用带零的按位 OR-operator (
| 0
),我们基本上对结果进行了取整,因为数字被转换为整数。 (包括 0 - 15)[例如:5]
无需深入了解逻辑运算的太多细节,按位或零意味着没有任何位发生变化。但是,由于按位运算适用于 32 位整数,因此结果被强制转换为整数。在没有太多性能开销的情况下,我们可以用专用的 floor 函数替换此操作以提高可读性。 ()
All bitwise operations except unsigned right shift, >>>, work on
signed 32-bit integers. So using bitwise operations will convert a
float to an integer.
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
。
- 通过将按位 AND-operator 与
0x3
结合使用,并将按位 OR-operator 与 0x8
结合使用,结果 (v
) 的值将是8,9,10,11.
- 旁注:这种情况永远不会发生在您的方法中,因为被替换的字符串仅包含
x
值。
有关按位运算的更多信息,请查看:https://www.w3schools.com/js/js_bitwise.asp
tldr: 给我一个方法,returns 打字稿中的 UUID.
使用@broofa 的最新版本 () 作为基础:
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);
});
}
我正在尝试构建一个函数来生成随机 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);*
它只是用一个随机的 [0123456789abcdef] 十六进制字符替换 'xxxx-xxxx-xxx-xxxx'
中的每个 'x'
。比你真正需要为 uuid 做的多一点。我通常这样做:
Math.random().toString().replace("0.", "")
你的方法确实生成了一个或多或少的随机字符串,可以用作 uuid。但是,它的可读性很差,换来的是非常短小的代码。此外,它不遵守 UUIDS 的 RFC 标准。如需函数的更新解决方案,请查看: and for more details on UUIDS:
但是,让我们特别关注您请求的行,让我尝试逐步解释它。
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
这一行定义了2个变量,分别是r
和v
。我们可以轻松地将其分成两行。
var r = Math.random() * 16 | 0;
var v = c == 'x' ? r : (r & 0x3 | 0x8);
变量定义 1:(r = Math.random() * 16 | 0;
):
Math.random()
是 returns 介于0
和1
之间的一个函数。 (0 包含 - 1 不包含)[例如:0.36342115]- 将该值乘以 16,结果介于
0
和16
之间。 (包含 0 - 不包含 16)[例如:5.8147384] - 通过使用带零的按位 OR-operator (
| 0
),我们基本上对结果进行了取整,因为数字被转换为整数。 (包括 0 - 15)[例如:5] 无需深入了解逻辑运算的太多细节,按位或零意味着没有任何位发生变化。但是,由于按位运算适用于 32 位整数,因此结果被强制转换为整数。在没有太多性能开销的情况下,我们可以用专用的 floor 函数替换此操作以提高可读性。 ()
All bitwise operations except unsigned right shift, >>>, work on signed 32-bit integers. So using bitwise operations will convert a float to an integer.
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
。 - 通过将按位 AND-operator 与
0x3
结合使用,并将按位 OR-operator 与0x8
结合使用,结果 (v
) 的值将是8,9,10,11. - 旁注:这种情况永远不会发生在您的方法中,因为被替换的字符串仅包含
x
值。
有关按位运算的更多信息,请查看:https://www.w3schools.com/js/js_bitwise.asp
tldr: 给我一个方法,returns 打字稿中的 UUID.
使用@broofa 的最新版本 () 作为基础:
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);
});
}