index.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. var hat = module.exports = function (bits, base) {
  2. if (!base) base = 16;
  3. if (bits === undefined) bits = 128;
  4. if (bits <= 0) return '0';
  5. var digits = Math.log(Math.pow(2, bits)) / Math.log(base);
  6. for (var i = 2; digits === Infinity; i *= 2) {
  7. digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i;
  8. }
  9. var rem = digits - Math.floor(digits);
  10. var res = '';
  11. for (var i = 0; i < Math.floor(digits); i++) {
  12. var x = Math.floor(Math.random() * base).toString(base);
  13. res = x + res;
  14. }
  15. if (rem) {
  16. var b = Math.pow(base, rem);
  17. var x = Math.floor(Math.random() * b).toString(base);
  18. res = x + res;
  19. }
  20. var parsed = parseInt(res, base);
  21. if (parsed !== Infinity && parsed >= Math.pow(2, bits)) {
  22. return hat(bits, base)
  23. }
  24. else return res;
  25. };
  26. hat.rack = function (bits, base, expandBy) {
  27. var fn = function (data) {
  28. var iters = 0;
  29. do {
  30. if (iters ++ > 10) {
  31. if (expandBy) bits += expandBy;
  32. else throw new Error('too many ID collisions, use more bits')
  33. }
  34. var id = hat(bits, base);
  35. } while (Object.hasOwnProperty.call(hats, id));
  36. hats[id] = data;
  37. return id;
  38. };
  39. var hats = fn.hats = {};
  40. fn.get = function (id) {
  41. return fn.hats[id];
  42. };
  43. fn.set = function (id, value) {
  44. fn.hats[id] = value;
  45. return fn;
  46. };
  47. fn.bits = bits || 128;
  48. fn.base = base || 16;
  49. return fn;
  50. };