uuid.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. inspect() {
  63. return `UUID v${this.version} ${this.toString()}`;
  64. }
  65. static check(uuid, offset = 0) {
  66. if (typeof uuid === "string") {
  67. uuid = uuid.toLowerCase();
  68. if (!/^[a-f0-9]{8}(-[a-f0-9]{4}){3}-([a-f0-9]{12})$/.test(uuid)) {
  69. return false;
  70. }
  71. if (uuid === "00000000-0000-0000-0000-000000000000") {
  72. return {
  73. version: undefined,
  74. variant: "nil",
  75. format: "ascii"
  76. };
  77. }
  78. return {
  79. version: (hex2byte[uuid[14] + uuid[15]] & 0xf0) >> 4,
  80. variant: getVariant((hex2byte[uuid[19] + uuid[20]] & 0xe0) >> 5),
  81. format: "ascii"
  82. };
  83. }
  84. if (Buffer.isBuffer(uuid)) {
  85. if (uuid.length < offset + 16) {
  86. return false;
  87. }
  88. let i = 0;
  89. for (; i < 16; i++) {
  90. if (uuid[offset + i] !== 0) {
  91. break;
  92. }
  93. }
  94. if (i === 16) {
  95. return {
  96. version: undefined,
  97. variant: "nil",
  98. format: "binary"
  99. };
  100. }
  101. return {
  102. version: (uuid[offset + 6] & 0xf0) >> 4,
  103. variant: getVariant((uuid[offset + 8] & 0xe0) >> 5),
  104. format: "binary"
  105. };
  106. }
  107. throw (0, _index().newError)("Unknown type of uuid", "ERR_UNKNOWN_UUID_TYPE");
  108. } // read stringified uuid into a Buffer
  109. static parse(input) {
  110. const buffer = Buffer.allocUnsafe(16);
  111. let j = 0;
  112. for (let i = 0; i < 16; i++) {
  113. buffer[i] = hex2byte[input[j++] + input[j++]];
  114. if (i === 3 || i === 5 || i === 7 || i === 9) {
  115. j += 1;
  116. }
  117. }
  118. return buffer;
  119. }
  120. } // from rfc4122#appendix-C
  121. exports.UUID = UUID;
  122. UUID.OID = UUID.parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"); // according to rfc4122#section-4.1.1
  123. function getVariant(bits) {
  124. switch (bits) {
  125. case 0:
  126. case 1:
  127. case 3:
  128. return "ncs";
  129. case 4:
  130. case 5:
  131. return "rfc4122";
  132. case 6:
  133. return "microsoft";
  134. default:
  135. return "future";
  136. }
  137. }
  138. var UuidEncoding;
  139. (function (UuidEncoding) {
  140. UuidEncoding[UuidEncoding["ASCII"] = 0] = "ASCII";
  141. UuidEncoding[UuidEncoding["BINARY"] = 1] = "BINARY";
  142. UuidEncoding[UuidEncoding["OBJECT"] = 2] = "OBJECT";
  143. })(UuidEncoding || (UuidEncoding = {})); // v1
  144. function uuidTimeBased(nodeId, encoding = UuidEncoding.ASCII) {
  145. let mTime = Date.now();
  146. let nTime = lastNTime + 1;
  147. const delta = mTime - lastMTime + (nTime - lastNTime) / 10000;
  148. if (delta < 0) {
  149. clockSeq = clockSeq + 1 & 0x3fff;
  150. nTime = 0;
  151. } else if (mTime > lastMTime) {
  152. nTime = 0;
  153. } else if (nTime >= 10000) {
  154. return moreThan10000;
  155. }
  156. lastMTime = mTime;
  157. lastNTime = nTime; // unix timestamp to gregorian epoch as per rfc4122#section-4.5
  158. mTime += 12219292800000;
  159. const buffer = Buffer.allocUnsafe(16);
  160. const myClockSeq = clockSeq;
  161. const timeLow = ((mTime & 0xfffffff) * 10000 + nTime) % 0x100000000;
  162. const timeHigh = mTime / 0x100000000 * 10000 & 0xfffffff;
  163. buffer[0] = timeLow >>> 24 & 0xff;
  164. buffer[1] = timeLow >>> 16 & 0xff;
  165. buffer[2] = timeLow >>> 8 & 0xff;
  166. buffer[3] = timeLow & 0xff;
  167. buffer[4] = timeHigh >>> 8 & 0xff;
  168. buffer[5] = timeHigh & 0xff;
  169. buffer[6] = timeHigh >>> 24 & 0x0f | 0x10;
  170. buffer[7] = timeHigh >>> 16 & 0x3f | 0x80;
  171. buffer[8] = myClockSeq >>> 8;
  172. buffer[9] = myClockSeq & 0xff;
  173. let result;
  174. switch (encoding) {
  175. case UuidEncoding.BINARY:
  176. buffer[10] = nodeId[0];
  177. buffer[11] = nodeId[1];
  178. buffer[12] = nodeId[2];
  179. buffer[13] = nodeId[3];
  180. buffer[14] = nodeId[4];
  181. buffer[15] = nodeId[5];
  182. result = buffer;
  183. break;
  184. case UuidEncoding.OBJECT:
  185. buffer[10] = nodeId[0];
  186. buffer[11] = nodeId[1];
  187. buffer[12] = nodeId[2];
  188. buffer[13] = nodeId[3];
  189. buffer[14] = nodeId[4];
  190. buffer[15] = nodeId[5];
  191. result = new UUID(buffer);
  192. break;
  193. default:
  194. 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]];
  195. break;
  196. }
  197. return result;
  198. } // v3 + v5
  199. function uuidNamed(name, hashMethod, version, namespace, encoding = UuidEncoding.ASCII) {
  200. const hash = (0, _crypto().createHash)(hashMethod);
  201. const nameIsNotAString = typeof name !== "string";
  202. if (nameIsNotAString && !Buffer.isBuffer(name)) {
  203. throw (0, _index().newError)(invalidName, "ERR_INVALID_UUID_NAME");
  204. }
  205. hash.update(namespace);
  206. hash.update(name);
  207. const buffer = hash.digest();
  208. let result;
  209. switch (encoding) {
  210. case UuidEncoding.BINARY:
  211. buffer[6] = buffer[6] & 0x0f | version;
  212. buffer[8] = buffer[8] & 0x3f | 0x80;
  213. result = buffer;
  214. break;
  215. case UuidEncoding.OBJECT:
  216. buffer[6] = buffer[6] & 0x0f | version;
  217. buffer[8] = buffer[8] & 0x3f | 0x80;
  218. result = new UUID(buffer);
  219. break;
  220. default:
  221. 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]];
  222. break;
  223. }
  224. return result;
  225. }
  226. function stringify(buffer) {
  227. 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]];
  228. } // according to rfc4122#section-4.1.7
  229. const nil = new UUID("00000000-0000-0000-0000-000000000000"); // UUID.v4 = uuidRandom
  230. // UUID.v4fast = uuidRandomFast
  231. // UUID.v3 = function(options, callback) {
  232. // return uuidNamed("md5", 0x30, options, callback)
  233. // }
  234. exports.nil = nil;
  235. //# sourceMappingURL=uuid.js.map