index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. (function (global, factory) {
  2. if (typeof define === "function" && define.amd) {
  3. define(["exports"], factory);
  4. } else if (typeof exports !== "undefined") {
  5. factory(exports);
  6. } else {
  7. var mod = {
  8. exports: {}
  9. };
  10. factory(mod.exports);
  11. global.Hashids = mod.exports;
  12. }
  13. })(this, function (_exports) {
  14. "use strict";
  15. Object.defineProperty(_exports, "__esModule", {
  16. value: true
  17. });
  18. _exports.default = void 0;
  19. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  20. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
  21. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
  22. var Hashids =
  23. /*#__PURE__*/
  24. function () {
  25. function Hashids() {
  26. var salt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  27. var minLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  28. var alphabet = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
  29. _classCallCheck(this, Hashids);
  30. var minAlphabetLength = 16;
  31. var sepDiv = 3.5;
  32. var guardDiv = 12;
  33. var errorAlphabetLength = 'error: alphabet must contain at least X unique characters';
  34. var errorAlphabetSpace = 'error: alphabet cannot contain spaces';
  35. var uniqueAlphabet = '',
  36. sepsLength,
  37. diff;
  38. /* funcs */
  39. this.escapeRegExp = function (s) {
  40. return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
  41. };
  42. this.parseInt = function (v, radix) {
  43. return /^(-|\+)?([0-9]+|Infinity)$/.test(v) ? parseInt(v, radix) : NaN;
  44. };
  45. /* alphabet vars */
  46. this.seps = 'cfhistuCFHISTU';
  47. this.minLength = parseInt(minLength, 10) > 0 ? minLength : 0;
  48. this.salt = typeof salt === 'string' ? salt : '';
  49. if (typeof alphabet === 'string') {
  50. this.alphabet = alphabet;
  51. }
  52. for (var i = 0; i !== this.alphabet.length; i++) {
  53. if (uniqueAlphabet.indexOf(this.alphabet.charAt(i)) === -1) {
  54. uniqueAlphabet += this.alphabet.charAt(i);
  55. }
  56. }
  57. this.alphabet = uniqueAlphabet;
  58. if (this.alphabet.length < minAlphabetLength) {
  59. throw errorAlphabetLength.replace('X', minAlphabetLength);
  60. }
  61. if (this.alphabet.search(' ') !== -1) {
  62. throw errorAlphabetSpace;
  63. }
  64. /*
  65. `this.seps` should contain only characters present in `this.alphabet`
  66. `this.alphabet` should not contains `this.seps`
  67. */
  68. for (var _i = 0; _i !== this.seps.length; _i++) {
  69. var j = this.alphabet.indexOf(this.seps.charAt(_i));
  70. if (j === -1) {
  71. this.seps = this.seps.substr(0, _i) + ' ' + this.seps.substr(_i + 1);
  72. } else {
  73. this.alphabet = this.alphabet.substr(0, j) + ' ' + this.alphabet.substr(j + 1);
  74. }
  75. }
  76. this.alphabet = this.alphabet.replace(/ /g, '');
  77. this.seps = this.seps.replace(/ /g, '');
  78. this.seps = this._shuffle(this.seps, this.salt);
  79. if (!this.seps.length || this.alphabet.length / this.seps.length > sepDiv) {
  80. sepsLength = Math.ceil(this.alphabet.length / sepDiv);
  81. if (sepsLength > this.seps.length) {
  82. diff = sepsLength - this.seps.length;
  83. this.seps += this.alphabet.substr(0, diff);
  84. this.alphabet = this.alphabet.substr(diff);
  85. }
  86. }
  87. this.alphabet = this._shuffle(this.alphabet, this.salt);
  88. var guardCount = Math.ceil(this.alphabet.length / guardDiv);
  89. if (this.alphabet.length < 3) {
  90. this.guards = this.seps.substr(0, guardCount);
  91. this.seps = this.seps.substr(guardCount);
  92. } else {
  93. this.guards = this.alphabet.substr(0, guardCount);
  94. this.alphabet = this.alphabet.substr(guardCount);
  95. }
  96. }
  97. _createClass(Hashids, [{
  98. key: "encode",
  99. value: function encode() {
  100. for (var _len = arguments.length, numbers = new Array(_len), _key = 0; _key < _len; _key++) {
  101. numbers[_key] = arguments[_key];
  102. }
  103. var ret = '';
  104. if (!numbers.length) {
  105. return ret;
  106. }
  107. if (numbers[0] && numbers[0].constructor === Array) {
  108. numbers = numbers[0];
  109. if (!numbers.length) {
  110. return ret;
  111. }
  112. }
  113. for (var i = 0; i !== numbers.length; i++) {
  114. numbers[i] = this.parseInt(numbers[i], 10);
  115. if (numbers[i] >= 0) {
  116. continue;
  117. } else {
  118. return ret;
  119. }
  120. }
  121. return this._encode(numbers);
  122. }
  123. }, {
  124. key: "decode",
  125. value: function decode(id) {
  126. var ret = [];
  127. if (!id || !id.length || typeof id !== 'string') {
  128. return ret;
  129. }
  130. return this._decode(id, this.alphabet);
  131. }
  132. }, {
  133. key: "encodeHex",
  134. value: function encodeHex(hex) {
  135. hex = hex.toString();
  136. if (!/^[0-9a-fA-F]+$/.test(hex)) {
  137. return '';
  138. }
  139. var numbers = hex.match(/[\w\W]{1,12}/g);
  140. for (var i = 0; i !== numbers.length; i++) {
  141. numbers[i] = parseInt('1' + numbers[i], 16);
  142. }
  143. return this.encode.apply(this, numbers);
  144. }
  145. }, {
  146. key: "decodeHex",
  147. value: function decodeHex(id) {
  148. var ret = [];
  149. var numbers = this.decode(id);
  150. for (var i = 0; i !== numbers.length; i++) {
  151. ret += numbers[i].toString(16).substr(1);
  152. }
  153. return ret;
  154. }
  155. }, {
  156. key: "_encode",
  157. value: function _encode(numbers) {
  158. var ret,
  159. alphabet = this.alphabet,
  160. numbersIdInt = 0;
  161. for (var i = 0; i !== numbers.length; i++) {
  162. numbersIdInt += numbers[i] % (i + 100);
  163. }
  164. ret = alphabet.charAt(numbersIdInt % alphabet.length);
  165. var lottery = ret;
  166. for (var _i2 = 0; _i2 !== numbers.length; _i2++) {
  167. var number = numbers[_i2];
  168. var buffer = lottery + this.salt + alphabet;
  169. alphabet = this._shuffle(alphabet, buffer.substr(0, alphabet.length));
  170. var last = this._toAlphabet(number, alphabet);
  171. ret += last;
  172. if (_i2 + 1 < numbers.length) {
  173. number %= last.charCodeAt(0) + _i2;
  174. var sepsIndex = number % this.seps.length;
  175. ret += this.seps.charAt(sepsIndex);
  176. }
  177. }
  178. if (ret.length < this.minLength) {
  179. var guardIndex = (numbersIdInt + ret[0].charCodeAt(0)) % this.guards.length;
  180. var guard = this.guards[guardIndex];
  181. ret = guard + ret;
  182. if (ret.length < this.minLength) {
  183. guardIndex = (numbersIdInt + ret[2].charCodeAt(0)) % this.guards.length;
  184. guard = this.guards[guardIndex];
  185. ret += guard;
  186. }
  187. }
  188. var halfLength = parseInt(alphabet.length / 2, 10);
  189. while (ret.length < this.minLength) {
  190. alphabet = this._shuffle(alphabet, alphabet);
  191. ret = alphabet.substr(halfLength) + ret + alphabet.substr(0, halfLength);
  192. var excess = ret.length - this.minLength;
  193. if (excess > 0) {
  194. ret = ret.substr(excess / 2, this.minLength);
  195. }
  196. }
  197. return ret;
  198. }
  199. }, {
  200. key: "_decode",
  201. value: function _decode(id, alphabet) {
  202. var ret = [],
  203. i = 0,
  204. r = new RegExp("[".concat(this.escapeRegExp(this.guards), "]"), 'g'),
  205. idBreakdown = id.replace(r, ' '),
  206. idArray = idBreakdown.split(' ');
  207. if (idArray.length === 3 || idArray.length === 2) {
  208. i = 1;
  209. }
  210. idBreakdown = idArray[i];
  211. if (typeof idBreakdown[0] !== 'undefined') {
  212. var lottery = idBreakdown[0];
  213. idBreakdown = idBreakdown.substr(1);
  214. r = new RegExp("[".concat(this.escapeRegExp(this.seps), "]"), 'g');
  215. idBreakdown = idBreakdown.replace(r, ' ');
  216. idArray = idBreakdown.split(' ');
  217. for (var j = 0; j !== idArray.length; j++) {
  218. var subId = idArray[j];
  219. var buffer = lottery + this.salt + alphabet;
  220. alphabet = this._shuffle(alphabet, buffer.substr(0, alphabet.length));
  221. ret.push(this._fromAlphabet(subId, alphabet));
  222. }
  223. if (this.encode(ret) !== id) {
  224. ret = [];
  225. }
  226. }
  227. return ret;
  228. }
  229. }, {
  230. key: "_shuffle",
  231. value: function _shuffle(alphabet, salt) {
  232. var integer;
  233. if (!salt.length) {
  234. return alphabet;
  235. }
  236. alphabet = alphabet.split("");
  237. for (var i = alphabet.length - 1, v = 0, p = 0, j = 0; i > 0; i--, v++) {
  238. v %= salt.length;
  239. p += integer = salt.charCodeAt(v);
  240. j = (integer + v + p) % i;
  241. var tmp = alphabet[j];
  242. alphabet[j] = alphabet[i];
  243. alphabet[i] = tmp;
  244. }
  245. alphabet = alphabet.join("");
  246. return alphabet;
  247. }
  248. }, {
  249. key: "_toAlphabet",
  250. value: function _toAlphabet(input, alphabet) {
  251. var id = '';
  252. do {
  253. id = alphabet.charAt(input % alphabet.length) + id;
  254. input = parseInt(input / alphabet.length, 10);
  255. } while (input);
  256. return id;
  257. }
  258. }, {
  259. key: "_fromAlphabet",
  260. value: function _fromAlphabet(input, alphabet) {
  261. return input.split("").map(function (item) {
  262. return alphabet.indexOf(item);
  263. }).reduce(function (carry, item) {
  264. return carry * alphabet.length + item;
  265. }, 0);
  266. }
  267. }]);
  268. return Hashids;
  269. }();
  270. _exports.default = Hashids;
  271. });
  272. //# sourceMappingURL=index.js.map