uuid.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.nil = exports.UUID = void 0;
  6. function _crypto() {
  7. const data = require("crypto");
  8. _crypto = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _index() {
  14. const data = require("./index");
  15. _index = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. const invalidName = "options.name must be either a string or a Buffer";
  21. const moreThan10000 = "can not generate more than 10000 UUIDs per second"; // Node ID according to rfc4122#section-4.5
  22. const randomHost = (0, _crypto().randomBytes)(16);
  23. randomHost[0] = randomHost[0] | 0x01; // randomize clockSeq initially, as per rfc4122#section-4.1.5
  24. const seed = (0, _crypto().randomBytes)(2);
  25. let clockSeq = (seed[0] | seed[1] << 8) & 0x3fff; // clock values
  26. let lastMTime = 0;
  27. let lastNTime = 0; // lookup table hex to byte
  28. const hex2byte = {}; // lookup table byte to hex
  29. const byte2hex = []; // populate lookup tables
  30. for (let i = 0; i < 256; i++) {
  31. const hex = (i + 0x100).toString(16).substr(1);
  32. hex2byte[hex] = i;
  33. byte2hex[i] = hex;
  34. } // UUID class
  35. class UUID {
  36. constructor(uuid) {
  37. this.ascii = null;
  38. this.binary = null;
  39. const check = UUID.check(uuid);
  40. if (!check) {
  41. throw new Error("not a UUID");
  42. }
  43. this.version = check.version;
  44. if (check.format === "ascii") {
  45. this.ascii = uuid;
  46. } else {
  47. this.binary = uuid;
  48. }
  49. }
  50. static v1() {
  51. return uuidTimeBased(randomHost);
  52. }
  53. static v5(name, namespace) {
  54. return uuidNamed(name, "sha1", 0x50, namespace);
  55. }
  56. toString() {
  57. if (this.ascii == null) {
  58. this.ascii = stringify(this.binary);
  59. }
  60. return this.ascii;
  61. }
  62. toBuffer() {
  63. if (this.binary == null) {
  64. this.binary = UUID.parse(this.ascii);
  65. }
  66. return Buffer.from(this.binary);
  67. }
  68. inspect() {
  69. return `UUID v${this.version} ${this.toString()}`;
  70. }
  71. static check(uuid, offset = 0) {
  72. if (typeof uuid === "string") {
  73. uuid = uuid.toLowerCase();
  74. if (!/^[a-f0-9]{8}(\-[a-f0-9]{4}){3}\-([a-f0-9]{12})$/.test(uuid)) {
  75. return false;
  76. }
  77. if (uuid === "00000000-0000-0000-0000-000000000000") {
  78. return {
  79. version: undefined,
  80. variant: "nil",
  81. format: "ascii"
  82. };
  83. }
  84. return {
  85. version: (hex2byte[uuid[14] + uuid[15]] & 0xf0) >> 4,
  86. variant: getVariant((hex2byte[uuid[19] + uuid[20]] & 0xe0) >> 5),
  87. format: "ascii"
  88. };
  89. }
  90. if (Buffer.isBuffer(uuid)) {
  91. if (uuid.length < offset + 16) {
  92. return false;
  93. }
  94. let i = 0;
  95. for (; i < 16; i++) {
  96. if (uuid[offset + i] !== 0) {
  97. break;
  98. }
  99. }
  100. if (i === 16) {
  101. return {
  102. version: undefined,
  103. variant: "nil",
  104. format: "binary"
  105. };
  106. }
  107. return {
  108. version: (uuid[offset + 6] & 0xf0) >> 4,
  109. variant: getVariant((uuid[offset + 8] & 0xe0) >> 5),
  110. format: "binary"
  111. };
  112. }
  113. throw (0, _index().newError)("Unknown type of uuid", "ERR_UNKNOWN_UUID_TYPE");
  114. } // read stringified uuid into a Buffer
  115. static parse(input) {
  116. const buffer = Buffer.allocUnsafe(16);
  117. let j = 0;
  118. for (let i = 0; i < 16; i++) {
  119. buffer[i] = hex2byte[input[j++] + input[j++]];
  120. if (i === 3 || i === 5 || i === 7 || i === 9) {
  121. j += 1;
  122. }
  123. }
  124. return buffer;
  125. }
  126. } // from rfc4122#appendix-C
  127. exports.UUID = UUID;
  128. UUID.URL = new UUID("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
  129. UUID.OID = UUID.parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); // according to rfc4122#section-4.1.1
  130. function getVariant(bits) {
  131. switch (bits) {
  132. case 0:
  133. case 1:
  134. case 3:
  135. return "ncs";
  136. case 4:
  137. case 5:
  138. return "rfc4122";
  139. case 6:
  140. return "microsoft";
  141. default:
  142. return "future";
  143. }
  144. }
  145. var UuidEncoding;
  146. (function (UuidEncoding) {
  147. UuidEncoding[UuidEncoding["ASCII"] = 0] = "ASCII";
  148. UuidEncoding[UuidEncoding["BINARY"] = 1] = "BINARY";
  149. UuidEncoding[UuidEncoding["OBJECT"] = 2] = "OBJECT";
  150. })(UuidEncoding || (UuidEncoding = {})); // v1
  151. function uuidTimeBased(nodeId, encoding = UuidEncoding.ASCII) {
  152. let mTime = Date.now();
  153. let nTime = lastNTime + 1;
  154. const delta = mTime - lastMTime + (nTime - lastNTime) / 10000;
  155. if (delta < 0) {
  156. clockSeq = clockSeq + 1 & 0x3fff;
  157. nTime = 0;
  158. } else if (mTime > lastMTime) {
  159. nTime = 0;
  160. } else if (nTime >= 10000) {
  161. return moreThan10000;
  162. }
  163. lastMTime = mTime;
  164. lastNTime = nTime; // unix timestamp to gregorian epoch as per rfc4122#section-4.5
  165. mTime += 12219292800000;
  166. const buffer = Buffer.allocUnsafe(16);
  167. const myClockSeq = clockSeq;
  168. const timeLow = ((mTime & 0xfffffff) * 10000 + nTime) % 0x100000000;
  169. const timeHigh = mTime / 0x100000000 * 10000 & 0xfffffff;
  170. buffer[0] = timeLow >>> 24 & 0xff;
  171. buffer[1] = timeLow >>> 16 & 0xff;
  172. buffer[2] = timeLow >>> 8 & 0xff;
  173. buffer[3] = timeLow & 0xff;
  174. buffer[4] = timeHigh >>> 8 & 0xff;
  175. buffer[5] = timeHigh & 0xff;
  176. buffer[6] = timeHigh >>> 24 & 0x0f | 0x10;
  177. buffer[7] = timeHigh >>> 16 & 0x3f | 0x80;
  178. buffer[8] = myClockSeq >>> 8;
  179. buffer[9] = myClockSeq & 0xff;
  180. let result;
  181. switch (encoding) {
  182. case UuidEncoding.BINARY:
  183. buffer[10] = nodeId[0];
  184. buffer[11] = nodeId[1];
  185. buffer[12] = nodeId[2];
  186. buffer[13] = nodeId[3];
  187. buffer[14] = nodeId[4];
  188. buffer[15] = nodeId[5];
  189. result = buffer;
  190. break;
  191. case UuidEncoding.OBJECT:
  192. buffer[10] = nodeId[0];
  193. buffer[11] = nodeId[1];
  194. buffer[12] = nodeId[2];
  195. buffer[13] = nodeId[3];
  196. buffer[14] = nodeId[4];
  197. buffer[15] = nodeId[5];
  198. result = new UUID(buffer);
  199. break;
  200. default:
  201. result = byte2hex[buffer[0]] + byte2hex[buffer[1]] + byte2hex[buffer[2]] + byte2hex[buffer[3]] + "-" + byte2hex[buffer[4]] + byte2hex[buffer[5]] + "-" + byte2hex[buffer[6]] + byte2hex[buffer[7]] + "-" + byte2hex[buffer[8]] + byte2hex[buffer[9]] + "-" + byte2hex[nodeId[0]] + byte2hex[nodeId[1]] + byte2hex[nodeId[2]] + byte2hex[nodeId[3]] + byte2hex[nodeId[4]] + byte2hex[nodeId[5]];
  202. break;
  203. }
  204. return result;
  205. } // v3 + v5
  206. function uuidNamed(name, hashMethod, version, namespace, encoding = UuidEncoding.ASCII) {
  207. const hash = (0, _crypto().createHash)(hashMethod);
  208. const nameIsNotAString = typeof name !== "string";
  209. if (nameIsNotAString && !Buffer.isBuffer(name)) {
  210. throw (0, _index().newError)(invalidName, "ERR_INVALID_UUID_NAME");
  211. }
  212. hash.update(namespace);
  213. hash.update(name, nameIsNotAString ? "latin1" : "utf8");
  214. const buffer = hash.digest();
  215. let result;
  216. switch (encoding) {
  217. case UuidEncoding.BINARY:
  218. buffer[6] = buffer[6] & 0x0f | version;
  219. buffer[8] = buffer[8] & 0x3f | 0x80;
  220. result = buffer;
  221. break;
  222. case UuidEncoding.OBJECT:
  223. buffer[6] = buffer[6] & 0x0f | version;
  224. buffer[8] = buffer[8] & 0x3f | 0x80;
  225. result = new UUID(buffer);
  226. break;
  227. default:
  228. result = byte2hex[buffer[0]] + byte2hex[buffer[1]] + byte2hex[buffer[2]] + byte2hex[buffer[3]] + "-" + byte2hex[buffer[4]] + byte2hex[buffer[5]] + "-" + byte2hex[buffer[6] & 0x0f | version] + byte2hex[buffer[7]] + "-" + byte2hex[buffer[8] & 0x3f | 0x80] + byte2hex[buffer[9]] + "-" + byte2hex[buffer[10]] + byte2hex[buffer[11]] + byte2hex[buffer[12]] + byte2hex[buffer[13]] + byte2hex[buffer[14]] + byte2hex[buffer[15]];
  229. break;
  230. }
  231. return result;
  232. }
  233. function stringify(buffer) {
  234. return byte2hex[buffer[0]] + byte2hex[buffer[1]] + byte2hex[buffer[2]] + byte2hex[buffer[3]] + "-" + byte2hex[buffer[4]] + byte2hex[buffer[5]] + "-" + byte2hex[buffer[6]] + byte2hex[buffer[7]] + "-" + byte2hex[buffer[8]] + byte2hex[buffer[9]] + "-" + byte2hex[buffer[10]] + byte2hex[buffer[11]] + byte2hex[buffer[12]] + byte2hex[buffer[13]] + byte2hex[buffer[14]] + byte2hex[buffer[15]];
  235. } // according to rfc4122#section-4.1.7
  236. const nil = new UUID("00000000-0000-0000-0000-000000000000"); // UUID.v4 = uuidRandom
  237. // UUID.v4fast = uuidRandomFast
  238. // UUID.v3 = function(options, callback) {
  239. // return uuidNamed("md5", 0x30, options, callback)
  240. // }
  241. exports.nil = nil;
  242. //# sourceMappingURL=uuid.js.map