You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.1 KiB

  1. 'use strict';
  2. var randomFromSeed = require('./random/random-from-seed');
  3. var ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';
  4. var alphabet;
  5. var previousSeed;
  6. var shuffled;
  7. function reset() {
  8. shuffled = false;
  9. }
  10. function setCharacters(_alphabet_) {
  11. if (!_alphabet_) {
  12. if (alphabet !== ORIGINAL) {
  13. alphabet = ORIGINAL;
  14. reset();
  15. }
  16. return;
  17. }
  18. if (_alphabet_ === alphabet) {
  19. return;
  20. }
  21. if (_alphabet_.length !== ORIGINAL.length) {
  22. throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. You submitted ' + _alphabet_.length + ' characters: ' + _alphabet_);
  23. }
  24. var unique = _alphabet_.split('').filter(function(item, ind, arr){
  25. return ind !== arr.lastIndexOf(item);
  26. });
  27. if (unique.length) {
  28. throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. These characters were not unique: ' + unique.join(', '));
  29. }
  30. alphabet = _alphabet_;
  31. reset();
  32. }
  33. function characters(_alphabet_) {
  34. setCharacters(_alphabet_);
  35. return alphabet;
  36. }
  37. function setSeed(seed) {
  38. randomFromSeed.seed(seed);
  39. if (previousSeed !== seed) {
  40. reset();
  41. previousSeed = seed;
  42. }
  43. }
  44. function shuffle() {
  45. if (!alphabet) {
  46. setCharacters(ORIGINAL);
  47. }
  48. var sourceArray = alphabet.split('');
  49. var targetArray = [];
  50. var r = randomFromSeed.nextValue();
  51. var characterIndex;
  52. while (sourceArray.length > 0) {
  53. r = randomFromSeed.nextValue();
  54. characterIndex = Math.floor(r * sourceArray.length);
  55. targetArray.push(sourceArray.splice(characterIndex, 1)[0]);
  56. }
  57. return targetArray.join('');
  58. }
  59. function getShuffled() {
  60. if (shuffled) {
  61. return shuffled;
  62. }
  63. shuffled = shuffle();
  64. return shuffled;
  65. }
  66. /**
  67. * lookup shuffled letter
  68. * @param index
  69. * @returns {string}
  70. */
  71. function lookup(index) {
  72. var alphabetShuffled = getShuffled();
  73. return alphabetShuffled[index];
  74. }
  75. module.exports = {
  76. characters: characters,
  77. seed: setSeed,
  78. lookup: lookup,
  79. shuffled: getShuffled
  80. };