123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- /**
- * UUID.js - RFC-compliant UUID Generator for JavaScript
- *
- * @file
- * @author LiosK
- * @version v4.2.9
- * @license Apache License 2.0: Copyright (c) 2010-2021 LiosK
- */
- /**
- * @class
- * @classdesc {@link UUID} object.
- * @hideconstructor
- */
- var UUID;
- UUID = (function(overwrittenUUID) {
- "use strict";
-
- // Core Component {{{
-
- /**
- * Generates a version 4 UUID as a hexadecimal string.
- * @returns {string} Hexadecimal UUID string.
- */
- UUID.generate = function() {
- var rand = UUID._getRandomInt, hex = UUID._hexAligner;
- return hex(rand(32), 8) // time_low
- + "-"
- + hex(rand(16), 4) // time_mid
- + "-"
- + hex(0x4000 | rand(12), 4) // time_hi_and_version
- + "-"
- + hex(0x8000 | rand(14), 4) // clock_seq_hi_and_reserved clock_seq_low
- + "-"
- + hex(rand(48), 12); // node
- };
-
- /**
- * Returns an unsigned x-bit random integer.
- * @private
- * @param {number} x Unsigned integer ranging from 0 to 53, inclusive.
- * @returns {number} Unsigned x-bit random integer (0 <= f(x) < 2^x).
- */
- UUID._getRandomInt = function(x) {
- if (x < 0 || x > 53) { return NaN; }
- var n = 0 | Math.random() * 0x40000000; // 1 << 30
- return x > 30 ? n + (0 | Math.random() * (1 << x - 30)) * 0x40000000 : n >>> 30 - x;
- };
-
- /**
- * Converts an integer to a zero-filled hexadecimal string.
- * @private
- * @param {number} num
- * @param {number} length
- * @returns {string}
- */
- UUID._hexAligner = function(num, length) {
- var str = num.toString(16), i = length - str.length, z = "0";
- for (; i > 0; i >>>= 1, z += z) { if (i & 1) { str = z + str; } }
- return str;
- };
-
- /**
- * Retains the value of 'UUID' global variable assigned before loading UUID.js.
- * @since 3.2
- * @type {any}
- */
- UUID.overwrittenUUID = overwrittenUUID;
-
- // }}}
-
- // Advanced Random Number Generator Component {{{
-
- (function() {
-
- var mathPRNG = UUID._getRandomInt;
-
- /**
- * Enables Math.random()-based pseudorandom number generator instead of cryptographically safer options.
- * @since v3.5.0
- * @deprecated This method is provided only to work around performance drawbacks of the safer algorithms.
- */
- UUID.useMathRandom = function() {
- UUID._getRandomInt = mathPRNG;
- };
-
- var crypto = null, cryptoPRNG = mathPRNG;
- if (typeof window !== "undefined" && (crypto = window.crypto || window.msCrypto)) {
- if (crypto.getRandomValues && typeof Uint32Array !== "undefined") {
- // Web Cryptography API
- cryptoPRNG = function(x) {
- if (x < 0 || x > 53) { return NaN; }
- var ns = new Uint32Array(x > 32 ? 2 : 1);
- ns = crypto.getRandomValues(ns) || ns;
- return x > 32 ? ns[0] + (ns[1] >>> 64 - x) * 0x100000000 : ns[0] >>> 32 - x;
- };
- }
- } else if (typeof require !== "undefined" && (crypto = require("crypto"))) {
- if (crypto.randomBytes) {
- // nodejs
- cryptoPRNG = function(x) {
- if (x < 0 || x > 53) { return NaN; }
- var buf = crypto.randomBytes(x > 32 ? 8 : 4), n = buf.readUInt32BE(0);
- return x > 32 ? n + (buf.readUInt32BE(4) >>> 64 - x) * 0x100000000 : n >>> 32 - x;
- };
- }
- }
- UUID._getRandomInt = cryptoPRNG;
-
- })();
-
- // }}}
-
- // UUID Object Component {{{
-
- /**
- * Names of UUID internal fields.
- * @type {string[]}
- * @constant
- * @since 3.0
- */
- UUID.FIELD_NAMES = ["timeLow", "timeMid", "timeHiAndVersion",
- "clockSeqHiAndReserved", "clockSeqLow", "node"];
-
- /**
- * Sizes of UUID internal fields.
- * @type {number[]}
- * @constant
- * @since 3.0
- */
- UUID.FIELD_SIZES = [32, 16, 16, 8, 8, 48];
-
- /**
- * Creates a version 4 {@link UUID} object.
- * @returns {UUID} Version 4 {@link UUID} object.
- * @since 3.0
- */
- UUID.genV4 = function() {
- var rand = UUID._getRandomInt;
- return new UUID()._init(rand(32), rand(16), // time_low time_mid
- 0x4000 | rand(12), // time_hi_and_version
- 0x80 | rand(6), // clock_seq_hi_and_reserved
- rand(8), rand(48)); // clock_seq_low node
- };
-
- /**
- * Converts a hexadecimal UUID string to a {@link UUID} object.
- * @param {string} strId Hexadecimal UUID string ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx").
- * @returns {UUID} {@link UUID} object or null.
- * @since 3.0
- */
- UUID.parse = function(strId) {
- var r, p = /^\s*(urn:uuid:|\{)?([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})(\})?\s*$/i;
- if (r = p.exec(strId)) {
- var l = r[1] || "", t = r[8] || "";
- if (((l + t) === "") ||
- (l === "{" && t === "}") ||
- (l.toLowerCase() === "urn:uuid:" && t === "")) {
- return new UUID()._init(parseInt(r[2], 16), parseInt(r[3], 16),
- parseInt(r[4], 16), parseInt(r[5], 16),
- parseInt(r[6], 16), parseInt(r[7], 16));
- }
- }
- return null;
- };
-
- /**
- * Initializes a {@link UUID} object.
- * @private
- * @constructs UUID
- * @param {number} [timeLow=0] time_low field (octet 0-3, uint32).
- * @param {number} [timeMid=0] time_mid field (octet 4-5, uint16).
- * @param {number} [timeHiAndVersion=0] time_hi_and_version field (octet 6-7, uint16).
- * @param {number} [clockSeqHiAndReserved=0] clock_seq_hi_and_reserved field (octet 8, uint8).
- * @param {number} [clockSeqLow=0] clock_seq_low field (octet 9, uint8).
- * @param {number} [node=0] node field (octet 10-15, uint48).
- * @returns {UUID} this.
- */
- UUID.prototype._init = function() {
- var names = UUID.FIELD_NAMES, sizes = UUID.FIELD_SIZES;
- var bin = UUID._binAligner, hex = UUID._hexAligner;
-
- /**
- * UUID internal field values as an array of integers.
- * @type {number[]}
- */
- this.intFields = new Array(6);
-
- /**
- * UUID internal field values as an array of binary strings.
- * @type {string[]}
- */
- this.bitFields = new Array(6);
-
- /**
- * UUID internal field values as an array of hexadecimal strings.
- * @type {string[]}
- */
- this.hexFields = new Array(6);
-
- for (var i = 0; i < 6; i++) {
- var intValue = parseInt(arguments[i] || 0);
- this.intFields[i] = this.intFields[names[i]] = intValue;
- this.bitFields[i] = this.bitFields[names[i]] = bin(intValue, sizes[i]);
- this.hexFields[i] = this.hexFields[names[i]] = hex(intValue, sizes[i] >>> 2);
- }
-
- /**
- * UUID version number.
- * @type {number}
- */
- this.version = (this.intFields.timeHiAndVersion >>> 12) & 0xF;
-
- /**
- * 128-bit binary string representation.
- * @type {string}
- */
- this.bitString = this.bitFields.join("");
-
- /**
- * Non-delimited hexadecimal string representation ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").
- * @type {string}
- * @since v3.3.0
- */
- this.hexNoDelim = this.hexFields.join("");
-
- /**
- * Hexadecimal string representation ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx").
- * @type {string}
- */
- this.hexString = this.hexFields[0] + "-" + this.hexFields[1] + "-" + this.hexFields[2]
- + "-" + this.hexFields[3] + this.hexFields[4] + "-" + this.hexFields[5];
-
- /**
- * URN string representation ("urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx").
- * @type {string}
- */
- this.urn = "urn:uuid:" + this.hexString;
-
- return this;
- };
-
- /**
- * Converts an integer to a zero-filled binary string.
- * @private
- * @param {number} num
- * @param {number} length
- * @returns {string}
- */
- UUID._binAligner = function(num, length) {
- var str = num.toString(2), i = length - str.length, z = "0";
- for (; i > 0; i >>>= 1, z += z) { if (i & 1) { str = z + str; } }
- return str;
- };
-
- /**
- * Returns the hexadecimal string representation.
- * @returns {string} {@link UUID#hexString}.
- */
- UUID.prototype.toString = function() { return this.hexString; };
-
- /**
- * Tests if two {@link UUID} objects are equal.
- * @param {UUID} uuid
- * @returns {boolean} True if two {@link UUID} objects are equal.
- */
- UUID.prototype.equals = function(uuid) {
- if (!(uuid instanceof UUID)) { return false; }
- for (var i = 0; i < 6; i++) {
- if (this.intFields[i] !== uuid.intFields[i]) { return false; }
- }
- return true;
- };
-
- /**
- * Nil UUID object.
- * @type {UUID}
- * @constant
- * @since v3.4.0
- */
- UUID.NIL = new UUID()._init(0, 0, 0, 0, 0, 0);
-
- // }}}
-
- // UUID Version 1 Component {{{
-
- /**
- * Creates a version 1 {@link UUID} object.
- * @returns {UUID} Version 1 {@link UUID} object.
- * @since 3.0
- */
- UUID.genV1 = function() {
- if (UUID._state == null) { UUID.resetState(); }
- var now = new Date().getTime(), st = UUID._state;
- if (now != st.timestamp) {
- if (now < st.timestamp) { st.sequence++; }
- st.timestamp = now;
- st.tick = UUID._getRandomInt(4);
- } else if (Math.random() < UUID._tsRatio && st.tick < 9984) {
- // advance the timestamp fraction at a probability
- // to compensate for the low timestamp resolution
- st.tick += 1 + UUID._getRandomInt(4);
- } else {
- st.sequence++;
- }
-
- // format time fields
- var tf = UUID._getTimeFieldValues(st.timestamp);
- var tl = tf.low + st.tick;
- var thav = (tf.hi & 0xFFF) | 0x1000; // set version '0001'
-
- // format clock sequence
- st.sequence &= 0x3FFF;
- var cshar = (st.sequence >>> 8) | 0x80; // set variant '10'
- var csl = st.sequence & 0xFF;
-
- return new UUID()._init(tl, tf.mid, thav, cshar, csl, st.node);
- };
-
- /**
- * Re-initializes the internal state for version 1 UUID creation.
- * @since 3.0
- */
- UUID.resetState = function() {
- UUID._state = new UUIDState();
- };
-
- function UUIDState() {
- var rand = UUID._getRandomInt;
- this.timestamp = 0;
- this.sequence = rand(14);
- this.node = (rand(8) | 1) * 0x10000000000 + rand(40); // set multicast bit '1'
- this.tick = rand(4); // timestamp fraction smaller than a millisecond
- }
-
- /**
- * Probability to advance the timestamp fraction: the ratio of tick movements to sequence increments.
- * @private
- * @type {number}
- */
- UUID._tsRatio = 1 / 4;
-
- /**
- * Persistent internal state for version 1 UUID creation.
- * @private
- * @type {UUIDState}
- */
- UUID._state = null;
-
- /**
- * @private
- * @param {Date|number} time ECMAScript Date Object or milliseconds from 1970-01-01.
- * @returns {any}
- */
- UUID._getTimeFieldValues = function(time) {
- var ts = time - Date.UTC(1582, 9, 15);
- var hm = ((ts / 0x100000000) * 10000) & 0xFFFFFFF;
- return { low: ((ts & 0xFFFFFFF) * 10000) % 0x100000000,
- mid: hm & 0xFFFF, hi: hm >>> 16, timestamp: ts };
- };
-
- // }}}
-
- // create local namespace
- function UUID() {}
-
- // for nodejs
- if (typeof module === "object" && typeof module.exports === "object") {
- module.exports = UUID;
- }
-
- return UUID;
-
- })(UUID);
-
- // vim: fdm=marker fmr&
|