-
-
Notifications
You must be signed in to change notification settings - Fork 903
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add parse/stringify/validate/version/NIL APIs (#479)
Add the following new APIs: - uuid.NIL The nil UUID string (all zeros) - uuid.parse() Convert UUID string to array of bytes - uuid.stringify() Convert array of bytes to UUID string - uuid.validate() Test a string to see if it is a valid UUID - uuid.version() Detect RFC version of a UUID This commit also adds more accurate validation when stringifying UUIDs and improves UUID parsing performance (for v3/v5 UUIDs) significantly (Thanks @awwit!). Co-authored-by: Christoph Tavan <dev@tavan.de> Co-authored-by: Ignat Prokopovich <ignatius.awwit@gmail.com> Co-authored-by: Robert Kieffer <robert@broofa.com> Co-authored-by: Linus Unnebäck <linus@folkdatorn.se>
- Loading branch information
1 parent
cba367a
commit 0e6c10b
Showing
25 changed files
with
819 additions
and
420 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
{ | ||
"files": [ | ||
{ "path": "./examples/browser-rollup/dist/v1-size.js", "maxSize": "0.8 kB" }, | ||
{ "path": "./examples/browser-rollup/dist/v3-size.js", "maxSize": "1.8 kB" }, | ||
{ "path": "./examples/browser-rollup/dist/v4-size.js", "maxSize": "0.5 kB" }, | ||
{ "path": "./examples/browser-rollup/dist/v5-size.js", "maxSize": "1.2 kB" }, | ||
{ "path": "./examples/browser-rollup/dist/v1-size.js", "maxSize": "1.0 kB" }, | ||
{ "path": "./examples/browser-rollup/dist/v3-size.js", "maxSize": "2.1 kB" }, | ||
{ "path": "./examples/browser-rollup/dist/v4-size.js", "maxSize": "0.7 kB" }, | ||
{ "path": "./examples/browser-rollup/dist/v5-size.js", "maxSize": "1.5 kB" }, | ||
|
||
{ "path": "./examples/browser-webpack/dist/v1-size.js", "maxSize": "1.0 kB" }, | ||
{ "path": "./examples/browser-webpack/dist/v3-size.js", "maxSize": "2.0 kB" }, | ||
{ "path": "./examples/browser-webpack/dist/v4-size.js", "maxSize": "0.7 kB" }, | ||
{ "path": "./examples/browser-webpack/dist/v5-size.js", "maxSize": "1.4 kB" } | ||
{ "path": "./examples/browser-webpack/dist/v1-size.js", "maxSize": "1.3 kB" }, | ||
{ "path": "./examples/browser-webpack/dist/v3-size.js", "maxSize": "2.5 kB" }, | ||
{ "path": "./examples/browser-webpack/dist/v4-size.js", "maxSize": "1.0 kB" }, | ||
{ "path": "./examples/browser-webpack/dist/v5-size.js", "maxSize": "1.9 kB" } | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default '00000000-0000-0000-0000-000000000000'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import validate from './validate.js'; | ||
|
||
function parse(uuid) { | ||
if (!validate(uuid)) { | ||
throw TypeError('Invalid UUID'); | ||
} | ||
|
||
let v; | ||
const arr = new Uint8Array(16); | ||
|
||
// Parse ########-....-....-....-............ | ||
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; | ||
arr[1] = (v >>> 16) & 0xff; | ||
arr[2] = (v >>> 8) & 0xff; | ||
arr[3] = v & 0xff; | ||
|
||
// Parse ........-####-....-....-............ | ||
arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; | ||
arr[5] = v & 0xff; | ||
|
||
// Parse ........-....-####-....-............ | ||
arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; | ||
arr[7] = v & 0xff; | ||
|
||
// Parse ........-....-....-####-............ | ||
arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; | ||
arr[9] = v & 0xff; | ||
|
||
// Parse ........-....-....-....-############ | ||
// (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) | ||
arr[10] = ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff; | ||
arr[11] = (v / 0x100000000) & 0xff; | ||
arr[12] = (v >>> 24) & 0xff; | ||
arr[13] = (v >>> 16) & 0xff; | ||
arr[14] = (v >>> 8) & 0xff; | ||
arr[15] = v & 0xff; | ||
|
||
return arr; | ||
} | ||
|
||
export default parse; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import validate from './validate.js'; | ||
|
||
/** | ||
* Convert array of 16 byte values to UUID string format of the form: | ||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX | ||
*/ | ||
const byteToHex = []; | ||
|
||
for (let i = 0; i < 256; ++i) { | ||
byteToHex.push((i + 0x100).toString(16).substr(1)); | ||
} | ||
|
||
function stringify(arr, offset = 0) { | ||
// Note: Be careful editing this code! It's been tuned for performance | ||
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 | ||
const uuid = ( | ||
byteToHex[arr[offset + 0]] + | ||
byteToHex[arr[offset + 1]] + | ||
byteToHex[arr[offset + 2]] + | ||
byteToHex[arr[offset + 3]] + | ||
'-' + | ||
byteToHex[arr[offset + 4]] + | ||
byteToHex[arr[offset + 5]] + | ||
'-' + | ||
byteToHex[arr[offset + 6]] + | ||
byteToHex[arr[offset + 7]] + | ||
'-' + | ||
byteToHex[arr[offset + 8]] + | ||
byteToHex[arr[offset + 9]] + | ||
'-' + | ||
byteToHex[arr[offset + 10]] + | ||
byteToHex[arr[offset + 11]] + | ||
byteToHex[arr[offset + 12]] + | ||
byteToHex[arr[offset + 13]] + | ||
byteToHex[arr[offset + 14]] + | ||
byteToHex[arr[offset + 15]] | ||
).toLowerCase(); | ||
|
||
// Consistency check for valid UUID. If this throws, it's likely due to one | ||
// of the following: | ||
// - One or more input array values don't map to a hex octet (leading to | ||
// "undefined" in the uuid) | ||
// - Invalid input values for the RFC `version` or `variant` fields | ||
if (!validate(uuid)) { | ||
throw TypeError('Stringified UUID is invalid'); | ||
} | ||
|
||
return uuid; | ||
} | ||
|
||
export default stringify; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.