RandomGenerator.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { inject, injectable } from 'inversify';
  2. import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
  3. import * as md5 from 'md5';
  4. import { Chance } from 'chance';
  5. import { IOptions } from '../interfaces/options/IOptions';
  6. import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
  7. import { Utils } from './Utils';
  8. import { ISourceCode } from '../interfaces/ISourceCode';
  9. @injectable()
  10. export class RandomGenerator implements IRandomGenerator {
  11. /**
  12. * @type {string}
  13. */
  14. public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  15. /**
  16. * @type {string}
  17. */
  18. public static readonly randomGeneratorPoolNumbers: string = '0123456789';
  19. /**
  20. * @type {string}
  21. */
  22. public static readonly randomGeneratorPoolHexadecimal: string = `abcdef${RandomGenerator.randomGeneratorPoolNumbers}`;
  23. /**
  24. * @type {IOptions}
  25. */
  26. private readonly options: IOptions;
  27. /**
  28. * @type {Set<string>}
  29. */
  30. private readonly randomVariableNameSet: Set <string> = new Set();
  31. /**
  32. * @type {Chance.Chance | Chance.SeededChance}
  33. */
  34. private readonly randomGenerator: Chance.Chance | Chance.SeededChance;
  35. /**
  36. * @type {ISourceCode}
  37. */
  38. private readonly sourceCode: ISourceCode;
  39. /**
  40. * @param sourceCode
  41. * @param options
  42. */
  43. constructor (
  44. @inject(ServiceIdentifiers.ISourceCode) sourceCode: ISourceCode,
  45. @inject(ServiceIdentifiers.IOptions) options: IOptions
  46. ) {
  47. this.sourceCode = sourceCode;
  48. this.options = options;
  49. if (options.seed !== 0) {
  50. this.randomGenerator = new Chance(this.getSeed());
  51. } else {
  52. this.randomGenerator = new Chance();
  53. }
  54. }
  55. /**
  56. * @returns {number}
  57. */
  58. public getMathRandom (): number {
  59. return this.getRandomInteger(0, 99999) / 100000;
  60. }
  61. /**
  62. * @param min
  63. * @param max
  64. * @returns {number}
  65. */
  66. public getRandomFloat (min: number, max: number): number {
  67. return this.getRandomGenerator().floating({
  68. min: min,
  69. max: max,
  70. fixed: 7
  71. });
  72. }
  73. /**
  74. * @returns {Chance.Chance}
  75. */
  76. public getRandomGenerator (): Chance.Chance {
  77. return this.randomGenerator;
  78. }
  79. /**
  80. * @param min
  81. * @param max
  82. * @returns {number}
  83. */
  84. public getRandomInteger (min: number, max: number): number {
  85. return this.getRandomGenerator().integer({
  86. min: min,
  87. max: max
  88. });
  89. }
  90. /**
  91. * @param length
  92. * @param pool
  93. * @returns {string}
  94. */
  95. public getRandomString (length: number, pool: string = RandomGenerator.randomGeneratorPool): string {
  96. return this.getRandomGenerator().string({ length, pool });
  97. }
  98. /**
  99. * @param length
  100. * @returns {string}
  101. */
  102. public getRandomVariableName (length: number): string {
  103. const prefix: string = `_${Utils.hexadecimalPrefix}`;
  104. const rangeMinInteger: number = 10000;
  105. const rangeMaxInteger: number = 99999999;
  106. const randomVariableName: string = `${prefix}${(
  107. Utils.decToHex(
  108. this.getRandomInteger(rangeMinInteger, rangeMaxInteger)
  109. )
  110. ).substr(0, length)}`;
  111. if (this.randomVariableNameSet.has(randomVariableName)) {
  112. return this.getRandomVariableName(length);
  113. }
  114. this.randomVariableNameSet.add(randomVariableName);
  115. return randomVariableName;
  116. }
  117. /**
  118. * We need to add numbers from md5 hash of source code to input seed to prevent same String Array name
  119. * for different bundles with same seed
  120. *
  121. * @returns {number}
  122. */
  123. private getSeed (): number {
  124. const md5Hash: string = md5(this.sourceCode.getSourceCode());
  125. return this.options.seed + Number(md5Hash.replace(/\D/g, ''));
  126. }
  127. }