-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
uuid-v4.ts
80 lines (71 loc) · 1.94 KB
/
uuid-v4.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
@module @ember-data/store
*/
const CRYPTO = (() => {
const hasWindow = typeof window !== 'undefined';
const isFastBoot = typeof FastBoot !== 'undefined';
if (isFastBoot) {
return {
getRandomValues(buffer: Uint8Array) {
try {
return (FastBoot as FastBoot).require('crypto').randomFillSync(buffer);
} catch (err) {
throw new Error(
'Using createRecord in Fastboot requires you to add the "crypto" package to "fastbootDependencies" in your package.json'
);
}
},
};
} else if (hasWindow && typeof window.crypto !== 'undefined') {
return window.crypto;
} else {
throw new Error('ember-data: Cannot find a valid way to generate local identifiers');
}
})();
// we might be able to optimize this by requesting more bytes than we need at a time
function rng() {
// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
let rnds8 = new Uint8Array(16);
return CRYPTO.getRandomValues(rnds8);
}
/*
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
const byteToHex: string[] = [];
for (let i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1);
}
function bytesToUuid(buf) {
let bth = byteToHex;
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
return [
bth[buf[0]],
bth[buf[1]],
bth[buf[2]],
bth[buf[3]],
'-',
bth[buf[4]],
bth[buf[5]],
'-',
bth[buf[6]],
bth[buf[7]],
'-',
bth[buf[8]],
bth[buf[9]],
'-',
bth[buf[10]],
bth[buf[11]],
bth[buf[12]],
bth[buf[13]],
bth[buf[14]],
bth[buf[15]],
].join('');
}
export default function uuidv4(): string {
let rnds = rng();
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
return bytesToUuid(rnds);
}