Bläddra i källkod

utils split on few utils classes

sanex3339 8 år sedan
förälder
incheckning
bbe95afcaa
48 ändrade filer med 636 tillägg och 713 borttagningar
  1. 155 271
      dist/index.js
  2. 2 2
      src/JavaScriptObfuscatorInternal.ts
  3. 2 2
      src/SourceMapCorrector.ts
  4. 0 329
      src/Utils.ts
  5. 1 1
      src/cli/CLIUtils.ts
  6. 1 1
      src/cli/JavaScriptObfuscatorCLI.ts
  7. 2 2
      src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts
  8. 2 2
      src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts
  9. 2 2
      src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts
  10. 3 3
      src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts
  11. 4 3
      src/custom-nodes/domain-lock-nodes/DomainLockNode.ts
  12. 2 2
      src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts
  13. 2 2
      src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts
  14. 2 2
      src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts
  15. 4 3
      src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts
  16. 4 4
      src/custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup.ts
  17. 1 1
      src/enums/NodeType.ts
  18. 1 1
      src/enums/ObfuscationEvents.ts
  19. 1 1
      src/enums/VisitorDirection.ts
  20. 2 2
      src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts
  21. 3 3
      src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts
  22. 3 3
      src/node-transformers/node-obfuscators/CatchClauseObfuscator.ts
  23. 3 3
      src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts
  24. 3 3
      src/node-transformers/node-obfuscators/FunctionObfuscator.ts
  25. 3 3
      src/node-transformers/node-obfuscators/LabeledStatementObfuscator.ts
  26. 1 1
      src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts
  27. 1 1
      src/node-transformers/node-obfuscators/ObjectExpressionObfuscator.ts
  28. 3 3
      src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts
  29. 2 2
      src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts
  30. 1 1
      src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts
  31. 10 8
      src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts
  32. 2 2
      src/node/NodeAppender.ts
  33. 1 1
      src/node/NodeUtils.ts
  34. 1 1
      src/options/OptionsNormalizer.ts
  35. 1 1
      src/storages/MapStorage.ts
  36. 1 1
      src/storages/string-array/StringArrayStorage.ts
  37. 1 1
      src/templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts
  38. 1 1
      src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts
  39. 1 1
      src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts
  40. 116 0
      src/utils/CryptUtils.ts
  41. 80 0
      src/utils/RandomGeneratorUtils.ts
  42. 140 0
      src/utils/Utils.ts
  43. 4 4
      test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts
  44. 3 3
      test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts
  45. 6 4
      test/index.spec.ts
  46. 38 0
      test/unit-tests/utils/CryptUtils.spec.ts
  47. 12 0
      test/unit-tests/utils/RandomGeneratorUtils.spec.ts
  48. 2 26
      test/unit-tests/utils/Utils.spec.ts

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 155 - 271
dist/index.js


+ 2 - 2
src/JavaScriptObfuscatorInternal.ts

@@ -12,7 +12,7 @@ import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
 import { IOptions } from './interfaces/options/IOptions';
 import { ISourceMapCorrector } from './interfaces/ISourceMapCorrector';
 
-import { Utils } from './Utils';
+import { RandomGeneratorUtils } from './utils/RandomGeneratorUtils';
 
 @injectable()
 export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
@@ -104,7 +104,7 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
      */
     public obfuscate (sourceCode: string): IObfuscationResult {
         if (this.options.seed !== 0) {
-            Utils.setRandomGeneratorSeed(this.options.seed);
+            RandomGeneratorUtils.setRandomGeneratorSeed(this.options.seed);
         }
 
         // parse AST tree

+ 2 - 2
src/SourceMapCorrector.ts

@@ -9,7 +9,7 @@ import { ISourceMapCorrector } from './interfaces/ISourceMapCorrector';
 
 import { SourceMapMode } from './enums/SourceMapMode';
 
-import { Utils } from './Utils';
+import { CryptUtils } from './utils/CryptUtils';
 
 @injectable()
 export class SourceMapCorrector implements ISourceMapCorrector {
@@ -63,7 +63,7 @@ export class SourceMapCorrector implements ISourceMapCorrector {
 
         switch (this.options.sourceMapMode) {
             case SourceMapMode.Inline:
-                sourceMappingUrl += `data:application/json;base64,${Utils.btoa(sourceMap)}`;
+                sourceMappingUrl += `data:application/json;base64,${CryptUtils.btoa(sourceMap)}`;
 
                 break;
 

+ 0 - 329
src/Utils.ts

@@ -1,329 +0,0 @@
-import { Chance } from 'chance';
-
-import { JSFuck } from './enums/JSFuck';
-
-const isEqual = require('is-equal');
-
-export class Utils {
-    /**
-     * @type {string}
-     */
-    public static readonly hexadecimalPrefix: string = '0x';
-
-    /**
-     * @type {string}
-     */
-    public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
-    /**
-     * @type {string}
-     */
-    public static readonly randomGeneratorPoolWithNumbers: string = `${Utils.randomGeneratorPool}0123456789`;
-
-    /**
-     * @type {Chance.Chance | Chance.SeededChance}
-     */
-    private static randomGenerator: Chance.Chance | Chance.SeededChance = new Chance();
-
-    /**
-     * @param array
-     * @param searchElement
-     * @returns {boolean}
-     */
-    public static arrayContains (array: any[], searchElement: any): boolean {
-        return array.indexOf(searchElement) >= 0;
-    }
-
-    /**
-     * @param array
-     * @param times
-     * @returns {T[]}
-     */
-    public static arrayRotate <T> (array: T[], times: number): T[] {
-        if (!array.length) {
-            throw new ReferenceError(`Cannot rotate empty array.`);
-        }
-
-        if (times <= 0) {
-            return array;
-        }
-
-        let newArray: T[] = array,
-            temp: T | undefined;
-
-        while (times--) {
-            temp = newArray.pop()!;
-            newArray.unshift(temp);
-        }
-
-        return newArray;
-    }
-
-    /**
-     * @param string
-     */
-    public static btoa (string: string): string {
-        const chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
-
-        let output: string = '';
-
-        string = encodeURIComponent(string).replace(/%([0-9A-F]{2})/g, (match, p1) => {
-            return String.fromCharCode(parseInt(`${Utils.hexadecimalPrefix}${p1}`));
-        });
-
-        for (
-            let block: number|undefined, charCode: number, idx: number = 0, map: string = chars;
-            string.charAt(idx | 0) || (map = '=', idx % 1);
-            output += map.charAt(63 & block >> 8 - idx % 1 * 8)
-        ) {
-            charCode = string.charCodeAt(idx += 3/4);
-
-            if (charCode > 0xFF) {
-                throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
-            }
-
-            block = block << 8 | charCode;
-        }
-
-        return output;
-    }
-
-    /**
-     * @param dec
-     * @returns {string}
-     */
-    public static decToHex (dec: number): string {
-        const radix: number = 16;
-
-        return Number(dec).toString(radix);
-    }
-
-    /**
-     * @param url
-     * @returns {string}
-     */
-    public static extractDomainFromUrl (url: string): string {
-        let domain: string;
-
-        if (url.indexOf('://') > -1 || url.indexOf('//') === 0) {
-            domain = url.split('/')[2];
-        } else {
-            domain = url.split('/')[0];
-        }
-
-        domain = domain.split(':')[0];
-
-        return domain;
-    }
-
-    /**
-     * @param min
-     * @param max
-     * @returns {number}
-     */
-    public static getRandomFloat (min: number, max: number): number {
-        return Utils.randomGenerator.floating({
-            min: min,
-            max: max,
-            fixed: 7
-        });
-    }
-
-    /**
-     * @returns {Chance.Chance}
-     */
-    public static getRandomGenerator (): Chance.Chance {
-        const randomGenerator: Chance.Chance = Utils.randomGenerator;
-
-        if (!randomGenerator) {
-            throw new Error(`\`randomGenerator\` static property is undefined`);
-        }
-
-        return Utils.randomGenerator;
-    }
-
-    /**
-     * @param min
-     * @param max
-     * @returns {number}
-     */
-    public static getRandomInteger (min: number, max: number): number {
-        return Utils.randomGenerator.integer({
-            min: min,
-            max: max
-        });
-    }
-
-    /**
-     * @param length
-     * @returns {string}
-     */
-    public static getRandomVariableName (length: number = 6): string {
-        const rangeMinInteger: number = 10000,
-            rangeMaxInteger: number = 99999999;
-
-        return `_${Utils.hexadecimalPrefix}${(
-            Utils.decToHex(
-                Utils.getRandomInteger(rangeMinInteger, rangeMaxInteger)
-            )
-        ).substr(0, length)}`;
-    }
-
-    /**
-     * @param str
-     * @param length
-     * @returns {string[]}
-     */
-    public static hideString(str: string, length: number): [string, string] {
-        const escapeRegExp: (s: string) => string = (s: string) =>
-            s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
-
-        const randomMerge: (s1: string, s2: string) => string = function (s1: string, s2: string): string {
-            let i1: number = -1,
-                i2: number = -1,
-                result: string = '';
-
-            while (i1 < s1.length || i2 < s2.length) {
-                if (Utils.getRandomFloat(0, 1) < 0.5 && i2 < s2.length) {
-                    result += s2.charAt(++i2);
-                } else {
-                    result += s1.charAt(++i1);
-                }
-            }
-
-            return result;
-        };
-
-        const randomString: string = Utils.randomGenerator.string({
-            length: length,
-            pool: Utils.randomGeneratorPool
-        });
-
-        let randomStringDiff: string = randomString.replace(
-            new RegExp('[' + escapeRegExp(str) + ']', 'g'),
-        '');
-
-        const randomStringDiffArray: string[] = randomStringDiff.split('');
-
-        Utils.randomGenerator.shuffle(randomStringDiffArray);
-        randomStringDiff = randomStringDiffArray.join('');
-
-        return [randomMerge(str, randomStringDiff), randomStringDiff];
-
-    }
-
-    /**
-     * @param number
-     * @returns {boolean}
-     */
-    public static isInteger (number: number): boolean {
-        return number % 1 === 0;
-    }
-
-    /**
-     * @param map
-     * @param value
-     * @returns {any}
-     */
-    public static mapGetFirstKeyOf(map: Map <any, any>, value: any): any {
-        for (var [key, storageValue] of map) {
-            if (isEqual(value, storageValue)) {
-                return key;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * RC4 symmetric cipher encryption/decryption
-     * https://gist.github.com/farhadi/2185197
-     *
-     * @param key
-     * @param string
-     * @returns {string}
-     */
-    public static rc4 (string: string, key: string) {
-        let s: number[] = [],
-            j: number = 0,
-            x: number,
-            result: string = '';
-
-        for (var i = 0; i < 256; i++) {
-            s[i] = i;
-        }
-
-        for (i = 0; i < 256; i++) {
-            j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
-            x = s[i];
-            s[i] = s[j];
-            s[j] = x;
-        }
-
-        i = 0;
-        j = 0;
-
-        for (let y = 0; y < string.length; y++) {
-            i = (i + 1) % 256;
-            j = (j + s[i]) % 256;
-            x = s[i];
-            s[i] = s[j];
-            s[j] = x;
-            result += String.fromCharCode(string.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
-        }
-
-        return result;
-    }
-
-    /**
-     * @param randomGeneratorSeed
-     */
-    public static setRandomGeneratorSeed (randomGeneratorSeed: number): void {
-        Utils.randomGenerator = new Chance(randomGeneratorSeed);
-    }
-
-    /**
-     * @param obj
-     * @returns {T}
-     */
-    public static strEnumify <T extends {[prop: string]: ''|string}> (obj: T): T {
-        return obj;
-    }
-
-    /**
-     * @param string
-     * @returns {string}
-     */
-    public static stringToJSFuck (string: string): string {
-        return Array
-            .from(string)
-            .map((character: string): string => {
-                return JSFuck[character] || character;
-            })
-            .join(' + ');
-    }
-
-    /**
-     * @param string
-     * @returns {string}
-     */
-    public static stringToUnicodeEscapeSequence (string: string): string {
-        const radix: number = 16;
-
-        let prefix: string,
-            regexp: RegExp = new RegExp('[\x00-\x7F]'),
-            template: string;
-
-        return `${string.replace(/[\s\S]/g, (escape: string): string => {
-            if (regexp.test(escape)) {
-                prefix = '\\x';
-                template = '0'.repeat(2);
-            } else {
-                prefix = '\\u';
-                template = '0'.repeat(4);
-            }
-
-            return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
-        })}`;
-    }
-}

+ 1 - 1
src/cli/CLIUtils.ts

@@ -4,7 +4,7 @@ import * as path from 'path';
 
 import { IPackageConfig } from '../interfaces/IPackageConfig';
 
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 export class CLIUtils {
     /**

+ 1 - 1
src/cli/JavaScriptObfuscatorCLI.ts

@@ -13,7 +13,7 @@ import { DEFAULT_PRESET } from '../preset-options/DefaultPreset';
 
 import { CLIUtils } from './CLIUtils';
 import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 export class JavaScriptObfuscatorCLI {
     /**

+ 2 - 2
src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts

@@ -10,7 +10,7 @@ import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-n
 import { initializable } from '../../decorators/Initializable';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
@@ -41,7 +41,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
      */
     public getCode (): string {
         return format(ConsoleOutputDisableExpressionTemplate(), {
-            consoleLogDisableFunctionName: Utils.getRandomVariableName(),
+            consoleLogDisableFunctionName: RandomGeneratorUtils.getRandomVariableName(),
             singleNodeCallControllerFunctionName: this.callsControllerFunctionName
         });
     }

+ 2 - 2
src/custom-nodes/console-output-nodes/group/ConsoleOutputCustomNodeGroup.ts

@@ -17,7 +17,7 @@ import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
 import { NodeAppender } from '../../../node/NodeAppender';
-import { Utils } from '../../../Utils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
@@ -96,7 +96,7 @@ export class ConsoleOutputCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
         }
 
-        const callsControllerFunctionName: string = Utils.getRandomVariableName();
+        const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
 
         const consoleOutputDisableExpressionNode: ICustomNode = this.customNodeFactory(CustomNodes.ConsoleOutputDisableExpressionNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);

+ 2 - 2
src/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionNode.ts

@@ -10,7 +10,7 @@ import { initializable } from '../../../decorators/Initializable';
 import { BinaryExpressionFunctionTemplate } from '../../../templates/custom-nodes/control-flow-replacers-nodes/binary-expression-control-flow-replacer-nodes/BinaryExpressionFunctionTemplate';
 
 import { AbstractCustomNode } from '../../AbstractCustomNode';
-import { Utils } from '../../../Utils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class BinaryExpressionFunctionNode extends AbstractCustomNode {
@@ -41,7 +41,7 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
      */
     public getCode (): string {
         return format(BinaryExpressionFunctionTemplate(), {
-            functionName: Utils.getRandomVariableName(1),
+            functionName: RandomGeneratorUtils.getRandomVariableName(1),
             operator: this.operator
         });
     }

+ 3 - 3
src/custom-nodes/debug-protection-nodes/group/DebugProtectionCustomNodeGroup.ts

@@ -17,7 +17,7 @@ import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
 import { NodeAppender } from '../../../node/NodeAppender';
-import { Utils } from '../../../Utils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
@@ -76,7 +76,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
         // debugProtectionFunctionIntervalNode append
         this.appendCustomNodeIfExist(CustomNodes.DebugProtectionFunctionIntervalNode, (customNode: ICustomNode) => {
             const programBodyLength: number = blockScopeNode.body.length;
-            const randomIndex: number = Utils.getRandomInteger(0, programBodyLength);
+            const randomIndex: number = RandomGeneratorUtils.getRandomInteger(0, programBodyLength);
 
             NodeAppender.insertNodeAtIndex(blockScopeNode, customNode.getNode(), randomIndex);
         });
@@ -89,7 +89,7 @@ export class DebugProtectionCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
         }
 
-        const debugProtectionFunctionName: string = Utils.getRandomVariableName();
+        const debugProtectionFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
 
         const debugProtectionFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionNode);
         const debugProtectionFunctionCallNode: ICustomNode = this.customNodeFactory(CustomNodes.DebugProtectionFunctionCallNode);

+ 4 - 3
src/custom-nodes/domain-lock-nodes/DomainLockNode.ts

@@ -10,7 +10,8 @@ import { initializable } from '../../decorators/Initializable';
 import { DomainLockNodeTemplate } from '../../templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
-import { Utils } from '../../Utils';
+import { CryptUtils } from '../../utils/CryptUtils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class DomainLockNode extends AbstractCustomNode {
@@ -41,10 +42,10 @@ export class DomainLockNode extends AbstractCustomNode {
      */
     public getCode (): string {
         let domainsString: string = this.options.domainLock.join(';'),
-            [hiddenDomainsString, diff]: string[] = Utils.hideString(domainsString, domainsString.length * 3);
+            [hiddenDomainsString, diff]: string[] = CryptUtils.hideString(domainsString, domainsString.length * 3);
 
         return format(DomainLockNodeTemplate(), {
-            domainLockFunctionName: Utils.getRandomVariableName(),
+            domainLockFunctionName: RandomGeneratorUtils.getRandomVariableName(),
             diff: diff,
             domains: hiddenDomainsString,
             singleNodeCallControllerFunctionName: this.callsControllerFunctionName

+ 2 - 2
src/custom-nodes/domain-lock-nodes/group/DomainLockCustomNodeGroup.ts

@@ -17,7 +17,7 @@ import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
 import { NodeAppender } from '../../../node/NodeAppender';
-import { Utils } from '../../../Utils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
@@ -96,7 +96,7 @@ export class DomainLockCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
         }
 
-        const callsControllerFunctionName: string = Utils.getRandomVariableName();
+        const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
 
         const domainLockNode: ICustomNode = this.customNodeFactory(CustomNodes.DomainLockNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);

+ 2 - 2
src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts

@@ -13,7 +13,7 @@ import { SelfDefendingTemplate } from '../../templates/custom-nodes/self-defendi
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class SelfDefendingUnicodeNode extends AbstractCustomNode {
@@ -45,7 +45,7 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
     public getCode (): string {
         return JavaScriptObfuscator.obfuscate(
             format(SelfDefendingTemplate(), {
-                selfDefendingFunctionName: Utils.getRandomVariableName(),
+                selfDefendingFunctionName: RandomGeneratorUtils.getRandomVariableName(),
                 singleNodeCallControllerFunctionName: this.callsControllerFunctionName
             }),
             Object.assign({},  NO_CUSTOM_NODES_PRESET, {

+ 2 - 2
src/custom-nodes/self-defending-nodes/group/SelfDefendingCustomNodeGroup.ts

@@ -17,7 +17,7 @@ import { ObfuscationEvents } from '../../../enums/ObfuscationEvents';
 
 import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
 import { NodeAppender } from '../../../node/NodeAppender';
-import { Utils } from '../../../Utils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
@@ -96,7 +96,7 @@ export class SelfDefendingCustomNodeGroup extends AbstractCustomNodeGroup {
             return;
         }
 
-        const callsControllerFunctionName: string = Utils.getRandomVariableName();
+        const callsControllerFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
 
         const selfDefendingUnicodeNode: ICustomNode = this.customNodeFactory(CustomNodes.SelfDefendingUnicodeNode);
         const nodeCallsControllerFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.NodeCallsControllerFunctionNode);

+ 4 - 3
src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts

@@ -15,7 +15,8 @@ import { StringArrayRotateFunctionTemplate } from '../../templates/custom-nodes/
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from '../../JavaScriptObfuscator';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
+import { Utils } from '../../utils/Utils';
 
 @injectable()
 export class StringArrayRotateFunctionNode extends AbstractCustomNode {
@@ -66,8 +67,8 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
      */
     public getCode (): string {
         let code: string = '',
-            timesName: string = Utils.getRandomVariableName(),
-            whileFunctionName: string = Utils.getRandomVariableName();
+            timesName: string = RandomGeneratorUtils.getRandomVariableName(),
+            whileFunctionName: string = RandomGeneratorUtils.getRandomVariableName();
 
         if (this.options.selfDefending) {
             code = format(SelfDefendingTemplate(), {

+ 4 - 4
src/custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup.ts

@@ -20,8 +20,8 @@ import { StringArrayNode } from '../StringArrayNode';
 
 import { AbstractCustomNodeGroup } from '../../AbstractCustomNodeGroup';
 import { NodeAppender } from '../../../node/NodeAppender';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 import { StringArrayStorage } from '../../../storages/string-array/StringArrayStorage';
-import { Utils } from '../../../Utils';
 
 @injectable()
 export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
@@ -105,13 +105,13 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
         const stringArrayCallsWrapper: ICustomNode = this.customNodeFactory(CustomNodes.StringArrayCallsWrapper);
         const stringArrayRotateFunctionNode: ICustomNode = this.customNodeFactory(CustomNodes.StringArrayRotateFunctionNode);
 
-        const stringArrayName: string = Utils.getRandomVariableName(StringArrayNode.ARRAY_RANDOM_LENGTH);
-        const stringArrayCallsWrapperName: string = Utils.getRandomVariableName(StringArrayNode.ARRAY_RANDOM_LENGTH);
+        const stringArrayName: string = RandomGeneratorUtils.getRandomVariableName(StringArrayNode.ARRAY_RANDOM_LENGTH);
+        const stringArrayCallsWrapperName: string = RandomGeneratorUtils.getRandomVariableName(StringArrayNode.ARRAY_RANDOM_LENGTH);
 
         let stringArrayRotateValue: number;
 
         if (this.options.rotateStringArray) {
-            stringArrayRotateValue = Utils.getRandomInteger(100, 500);
+            stringArrayRotateValue = RandomGeneratorUtils.getRandomInteger(100, 500);
         } else {
             stringArrayRotateValue = 0;
         }

+ 1 - 1
src/enums/NodeType.ts

@@ -1,4 +1,4 @@
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 export const NodeType: any = Utils.strEnumify({
     ArrayExpression: 'ArrayExpression',

+ 1 - 1
src/enums/ObfuscationEvents.ts

@@ -1,6 +1,6 @@
 import { TObfuscationEvent } from '../types/event-emitters/TObfuscationEvent';
 
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 export const ObfuscationEvents: {
     AfterObfuscation: TObfuscationEvent,

+ 1 - 1
src/enums/VisitorDirection.ts

@@ -1,4 +1,4 @@
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 export const VisitorDirection: any = Utils.strEnumify({
     enter: 'enter',

+ 2 - 2
src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts

@@ -19,7 +19,7 @@ import { ControlFlowStorage } from '../../storages/control-flow/ControlFlowStora
 import { ControlFlowStorageNode } from '../../custom-nodes/control-flow-storage-nodes/ControlFlowStorageNode';
 import { Node } from '../../node/Node';
 import { NodeAppender } from '../../node/NodeAppender';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
@@ -55,7 +55,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
         }
 
         const controlFlowStorage: IStorage <ICustomNode> = new ControlFlowStorage();
-        const controlFlowStorageCustomNodeName: string = Utils.getRandomVariableName(6);
+        const controlFlowStorageCustomNodeName: string = RandomGeneratorUtils.getRandomVariableName(6);
 
         estraverse.replace(functionNode.body, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {

+ 3 - 3
src/node-transformers/node-control-flow-transformers/control-flow-replacers/AbstractControlFlowReplacer.ts

@@ -8,7 +8,7 @@ import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../../../interfaces/options/IOptions';
 import { IStorage } from '../../../interfaces/storages/IStorage';
 
-import { Utils } from '../../../Utils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 
 @injectable()
 export abstract class AbstractControlFlowReplacer implements IControlFlowReplacer {
@@ -30,9 +30,9 @@ export abstract class AbstractControlFlowReplacer implements IControlFlowReplace
      * @returns {string}
      */
     protected static getStorageKey (): string {
-        return Utils.getRandomGenerator().string({
+        return RandomGeneratorUtils.getRandomGenerator().string({
             length: 3,
-            pool: Utils.randomGeneratorPool
+            pool: RandomGeneratorUtils.randomGeneratorPool
         });
     }
 

+ 3 - 3
src/node-transformers/node-obfuscators/CatchClauseObfuscator.ts

@@ -14,7 +14,7 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { IdentifierReplacer } from './replacers/IdentifierReplacer';
 import { Node } from '../../node/Node';
 import { NodeUtils } from '../../node/NodeUtils';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 /**
  * replaces:
@@ -48,9 +48,9 @@ export class CatchClauseObfuscator extends AbstractNodeTransformer {
      * @param catchClauseNode
      */
     public transformNode (catchClauseNode: ESTree.CatchClause): void {
-        this.identifierReplacer.setPrefix(Utils.getRandomGenerator().string({
+        this.identifierReplacer.setPrefix(RandomGeneratorUtils.getRandomGenerator().string({
             length: 5,
-            pool: Utils.randomGeneratorPool
+            pool: RandomGeneratorUtils.randomGeneratorPool
         }));
 
         this.storeCatchClauseParam(catchClauseNode);

+ 3 - 3
src/node-transformers/node-obfuscators/FunctionDeclarationObfuscator.ts

@@ -16,7 +16,7 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { IdentifierReplacer } from './replacers/IdentifierReplacer';
 import { Node } from '../../node/Node';
 import { NodeUtils } from '../../node/NodeUtils';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 /**
  * replaces:
@@ -52,9 +52,9 @@ export class FunctionDeclarationObfuscator extends AbstractNodeTransformer {
      * @param parentNode
      */
     public transformNode (functionDeclarationNode: ESTree.FunctionDeclaration, parentNode: ESTree.Node): void {
-        this.identifierReplacer.setPrefix(Utils.getRandomGenerator().string({
+        this.identifierReplacer.setPrefix(RandomGeneratorUtils.getRandomGenerator().string({
             length: 5,
-            pool: Utils.randomGeneratorPool
+            pool: RandomGeneratorUtils.randomGeneratorPool
         }));
 
         const blockScopeOfFunctionDeclarationNode: TNodeWithBlockStatement = NodeUtils

+ 3 - 3
src/node-transformers/node-obfuscators/FunctionObfuscator.ts

@@ -14,7 +14,7 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { IdentifierReplacer } from './replacers/IdentifierReplacer';
 import { Node } from '../../node/Node';
 import { NodeUtils } from '../../node/NodeUtils';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 /**
  * replaces:
@@ -48,9 +48,9 @@ export class FunctionObfuscator extends AbstractNodeTransformer {
      * @param functionNode
      */
     public transformNode (functionNode: ESTree.Function): void {
-        this.identifierReplacer.setPrefix(Utils.getRandomGenerator().string({
+        this.identifierReplacer.setPrefix(RandomGeneratorUtils.getRandomGenerator().string({
             length: 5,
-            pool: Utils.randomGeneratorPool
+            pool: RandomGeneratorUtils.randomGeneratorPool
         }));
 
         this.storeFunctionParams(functionNode);

+ 3 - 3
src/node-transformers/node-obfuscators/LabeledStatementObfuscator.ts

@@ -14,7 +14,7 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { IdentifierReplacer } from './replacers/IdentifierReplacer';
 import { Node } from '../../node/Node';
 import { NodeUtils } from '../../node/NodeUtils';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 /**
  * replaces:
@@ -56,9 +56,9 @@ export class LabeledStatementObfuscator extends AbstractNodeTransformer {
      * @param labeledStatementNode
      */
     public transformNode (labeledStatementNode: ESTree.LabeledStatement): void {
-        this.identifierReplacer.setPrefix(Utils.getRandomGenerator().string({
+        this.identifierReplacer.setPrefix(RandomGeneratorUtils.getRandomGenerator().string({
             length: 5,
-            pool: Utils.randomGeneratorPool
+            pool: RandomGeneratorUtils.randomGeneratorPool
         }));
 
         this.storeLabeledStatementName(labeledStatementNode);

+ 1 - 1
src/node-transformers/node-obfuscators/MethodDefinitionObfuscator.ts

@@ -11,7 +11,7 @@ import { NodeObfuscatorsReplacers } from '../../enums/container/NodeObfuscatorsR
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { Node } from '../../node/Node';
-import { Utils } from '../../Utils';
+import { Utils } from '../../utils/Utils';
 
 /**
  * replaces:

+ 1 - 1
src/node-transformers/node-obfuscators/ObjectExpressionObfuscator.ts

@@ -11,7 +11,7 @@ import { NodeType } from '../../enums/NodeType';
 
 import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { Node } from '../../node/Node';
-import { Utils } from '../../Utils';
+import { Utils } from '../../utils/Utils';
 
 /**
  * replaces:

+ 3 - 3
src/node-transformers/node-obfuscators/VariableDeclarationObfuscator.ts

@@ -16,7 +16,7 @@ import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
 import { IdentifierReplacer } from './replacers/IdentifierReplacer';
 import { Node } from '../../node/Node';
 import { NodeUtils } from '../../node/NodeUtils';
-import { Utils } from '../../Utils';
+import { RandomGeneratorUtils } from '../../utils/RandomGeneratorUtils';
 
 /**
  * replaces:
@@ -53,9 +53,9 @@ export class VariableDeclarationObfuscator extends AbstractNodeTransformer {
      * @param parentNode
      */
     public transformNode (variableDeclarationNode: ESTree.VariableDeclaration, parentNode: ESTree.Node): void {
-        this.identifierReplacer.setPrefix(Utils.getRandomGenerator().string({
+        this.identifierReplacer.setPrefix(RandomGeneratorUtils.getRandomGenerator().string({
             length: 5,
-            pool: Utils.randomGeneratorPool
+            pool: RandomGeneratorUtils.randomGeneratorPool
         }));
 
         const blockScopeOfVariableDeclarationNode: TNodeWithBlockStatement = NodeUtils

+ 2 - 2
src/node-transformers/node-obfuscators/replacers/IdentifierReplacer.ts

@@ -4,7 +4,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
 import { IOptions } from '../../../interfaces/options/IOptions';
 
 import { AbstractReplacer } from './AbstractReplacer';
-import { Utils } from '../../../Utils';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
 
 @injectable()
 export class IdentifierReplacer extends AbstractReplacer {
@@ -60,7 +60,7 @@ export class IdentifierReplacer extends AbstractReplacer {
         }
 
         if (!this.isReservedName(nodeName)) {
-            this.namesMap.set(`${nodeName}-${this.uniquePrefix}`, Utils.getRandomVariableName());
+            this.namesMap.set(`${nodeName}-${this.uniquePrefix}`, RandomGeneratorUtils.getRandomVariableName());
         }
     }
 

+ 1 - 1
src/node-transformers/node-obfuscators/replacers/NumberLiteralReplacer.ts

@@ -4,7 +4,7 @@ import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
 import { IOptions } from '../../../interfaces/options/IOptions';
 
 import { AbstractReplacer } from './AbstractReplacer';
-import { Utils } from '../../../Utils';
+import { Utils } from '../../../utils/Utils';
 
 @injectable()
 export class NumberLiteralReplacer extends AbstractReplacer {

+ 10 - 8
src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts

@@ -11,9 +11,11 @@ import { IStorage } from '../../../interfaces/storages/IStorage';
 import { StringArrayEncoding } from '../../../enums/StringArrayEncoding';
 
 import { AbstractReplacer } from './AbstractReplacer';
-import { CustomNodeGroups } from '../../../enums/container/CustomNodeGroups';
-import { Utils } from '../../../Utils';
+import { CryptUtils } from '../../../utils/CryptUtils';
 import { CustomNodes } from '../../../enums/container/CustomNodes';
+import { CustomNodeGroups } from '../../../enums/container/CustomNodeGroups';
+import { RandomGeneratorUtils } from '../../../utils/RandomGeneratorUtils';
+import { Utils } from '../../../utils/Utils';
 
 @injectable()
 export class StringLiteralReplacer extends AbstractReplacer {
@@ -25,8 +27,8 @@ export class StringLiteralReplacer extends AbstractReplacer {
     /**
      * @type {string[]}
      */
-    private static readonly rc4Keys: string[] = Utils.getRandomGenerator()
-        .n(() => Utils.getRandomGenerator().string({length: 4}), 50);
+    private static readonly rc4Keys: string[] = RandomGeneratorUtils.getRandomGenerator()
+        .n(() => RandomGeneratorUtils.getRandomGenerator().string({length: 4}), 50);
 
     /**
      * @type {IStorage<ICustomNodeGroup>}
@@ -53,7 +55,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
     public replace (nodeValue: string): string {
         const replaceWithStringArrayFlag: boolean = (
             nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray
-            && Utils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold
+            && RandomGeneratorUtils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold
         );
 
         if (this.options.stringArray && replaceWithStringArrayFlag) {
@@ -78,13 +80,13 @@ export class StringLiteralReplacer extends AbstractReplacer {
 
         switch (this.options.stringArrayEncoding) {
             case StringArrayEncoding.base64:
-                value = Utils.btoa(value);
+                value = CryptUtils.btoa(value);
 
                 break;
 
             case StringArrayEncoding.rc4:
-                rc4Key = Utils.getRandomGenerator().pickone(StringLiteralReplacer.rc4Keys);
-                value = Utils.btoa(Utils.rc4(value, rc4Key));
+                rc4Key = RandomGeneratorUtils.getRandomGenerator().pickone(StringLiteralReplacer.rc4Keys);
+                value = CryptUtils.btoa(CryptUtils.rc4(value, rc4Key));
 
                 break;
         }

+ 2 - 2
src/node/NodeAppender.ts

@@ -5,7 +5,7 @@ import { TStatement } from '../types/node/TStatement';
 
 import { IStackTraceData } from '../interfaces/stack-trace-analyzer/IStackTraceData';
 
-import { Utils } from '../Utils';
+import { RandomGeneratorUtils } from '../utils/RandomGeneratorUtils';
 
 /**
  * This class appends node into a first deepest BlockStatement in order of function calls
@@ -101,7 +101,7 @@ export class NodeAppender {
      * @param stackTraceRootLength
      */
     public static getRandomStackTraceIndex (stackTraceRootLength: number): number {
-        return Utils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1)));
+        return RandomGeneratorUtils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1)));
     }
 
     /**

+ 1 - 1
src/node/NodeUtils.ts

@@ -9,7 +9,7 @@ import { TStatement } from '../types/node/TStatement';
 import { NodeType } from '../enums/NodeType';
 
 import { Node } from './Node';
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 export class NodeUtils {
     /**

+ 1 - 1
src/options/OptionsNormalizer.ts

@@ -3,7 +3,7 @@ import { IOptions } from '../interfaces/options/IOptions';
 
 import { TOptionsNormalizerRule } from '../types/options/TOptionsNormalizerRule';
 
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 export class OptionsNormalizer {
     /**

+ 1 - 1
src/storages/MapStorage.ts

@@ -4,7 +4,7 @@ import { IStorage } from '../interfaces/storages/IStorage';
 
 import { initializable } from '../decorators/Initializable';
 
-import { Utils } from '../Utils';
+import { Utils } from '../utils/Utils';
 
 @injectable()
 export abstract class MapStorage <T> implements IStorage <T> {

+ 1 - 1
src/storages/string-array/StringArrayStorage.ts

@@ -1,5 +1,5 @@
 import { ArrayStorage } from '../ArrayStorage';
-import { Utils } from '../../Utils';
+import { Utils } from '../../utils/Utils';
 
 export class StringArrayStorage extends ArrayStorage <string> {
     constructor () {

+ 1 - 1
src/templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts

@@ -1,4 +1,4 @@
-import { Utils } from '../../../../Utils';
+import { Utils } from '../../../../utils/Utils';
 
 /**
  * SelfDefendingTemplate. Enters code in infinity loop.

+ 1 - 1
src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts

@@ -1,4 +1,4 @@
-import { Utils } from '../../../../Utils';
+import { Utils } from '../../../../utils/Utils';
 
 /**
  * @returns {string}

+ 1 - 1
src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts

@@ -1,4 +1,4 @@
-import { Utils } from '../../../../Utils';
+import { Utils } from '../../../../utils/Utils';
 
 /**
  * SelfDefendingTemplate. Enter code in infinity loop.

+ 116 - 0
src/utils/CryptUtils.ts

@@ -0,0 +1,116 @@
+import { RandomGeneratorUtils } from './RandomGeneratorUtils';
+import { Utils } from './Utils';
+
+export class CryptUtils {
+    /**
+     * @param string
+     */
+    public static btoa (string: string): string {
+        const chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+
+        let output: string = '';
+
+        string = encodeURIComponent(string).replace(/%([0-9A-F]{2})/g, (match, p1) => {
+            return String.fromCharCode(parseInt(`${Utils.hexadecimalPrefix}${p1}`));
+        });
+
+        for (
+            let block: number|undefined, charCode: number, idx: number = 0, map: string = chars;
+            string.charAt(idx | 0) || (map = '=', idx % 1);
+            output += map.charAt(63 & block >> 8 - idx % 1 * 8)
+        ) {
+            charCode = string.charCodeAt(idx += 3/4);
+
+            if (charCode > 0xFF) {
+                throw new Error("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
+            }
+
+            block = block << 8 | charCode;
+        }
+
+        return output;
+    }
+
+    /**
+     * @param str
+     * @param length
+     * @returns {string[]}
+     */
+    public static hideString(str: string, length: number): [string, string] {
+        const escapeRegExp: (s: string) => string = (s: string) =>
+            s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+
+        const randomMerge: (s1: string, s2: string) => string = function (s1: string, s2: string): string {
+            let i1: number = -1,
+                i2: number = -1,
+                result: string = '';
+
+            while (i1 < s1.length || i2 < s2.length) {
+                if (RandomGeneratorUtils.getRandomFloat(0, 1) < 0.5 && i2 < s2.length) {
+                    result += s2.charAt(++i2);
+                } else {
+                    result += s1.charAt(++i1);
+                }
+            }
+
+            return result;
+        };
+
+        const randomString: string = RandomGeneratorUtils.randomGenerator.string({
+            length: length,
+            pool: RandomGeneratorUtils.randomGeneratorPool
+        });
+
+        let randomStringDiff: string = randomString.replace(
+            new RegExp('[' + escapeRegExp(str) + ']', 'g'),
+            '');
+
+        const randomStringDiffArray: string[] = randomStringDiff.split('');
+
+        RandomGeneratorUtils.randomGenerator.shuffle(randomStringDiffArray);
+        randomStringDiff = randomStringDiffArray.join('');
+
+        return [randomMerge(str, randomStringDiff), randomStringDiff];
+
+    }
+
+    /**
+     * RC4 symmetric cipher encryption/decryption
+     * https://gist.github.com/farhadi/2185197
+     *
+     * @param key
+     * @param string
+     * @returns {string}
+     */
+    public static rc4 (string: string, key: string): string {
+        let s: number[] = [],
+            j: number = 0,
+            x: number,
+            result: string = '';
+
+        for (var i = 0; i < 256; i++) {
+            s[i] = i;
+        }
+
+        for (i = 0; i < 256; i++) {
+            j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
+            x = s[i];
+            s[i] = s[j];
+            s[j] = x;
+        }
+
+        i = 0;
+        j = 0;
+
+        for (let y = 0; y < string.length; y++) {
+            i = (i + 1) % 256;
+            j = (j + s[i]) % 256;
+            x = s[i];
+            s[i] = s[j];
+            s[j] = x;
+            result += String.fromCharCode(string.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
+        }
+
+        return result;
+    }
+}

+ 80 - 0
src/utils/RandomGeneratorUtils.ts

@@ -0,0 +1,80 @@
+import { Chance } from 'chance';
+
+import { Utils } from './Utils';
+
+export class RandomGeneratorUtils {
+    /**
+     * @type {string}
+     */
+    public static readonly randomGeneratorPool: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+
+    /**
+     * @type {string}
+     */
+    public static readonly randomGeneratorPoolWithNumbers: string = `${RandomGeneratorUtils.randomGeneratorPool}0123456789`;
+
+    /**
+     * @type {Chance.Chance | Chance.SeededChance}
+     */
+    public static randomGenerator: Chance.Chance | Chance.SeededChance = new Chance();
+
+    /**
+     * @param min
+     * @param max
+     * @returns {number}
+     */
+    public static getRandomFloat (min: number, max: number): number {
+        return RandomGeneratorUtils.randomGenerator.floating({
+            min: min,
+            max: max,
+            fixed: 7
+        });
+    }
+
+    /**
+     * @returns {Chance.Chance}
+     */
+    public static getRandomGenerator (): Chance.Chance {
+        const randomGenerator: Chance.Chance = RandomGeneratorUtils.randomGenerator;
+
+        if (!randomGenerator) {
+            throw new Error(`\`randomGenerator\` static property is undefined`);
+        }
+
+        return RandomGeneratorUtils.randomGenerator;
+    }
+
+    /**
+     * @param min
+     * @param max
+     * @returns {number}
+     */
+    public static getRandomInteger (min: number, max: number): number {
+        return RandomGeneratorUtils.randomGenerator.integer({
+            min: min,
+            max: max
+        });
+    }
+
+    /**
+     * @param length
+     * @returns {string}
+     */
+    public static getRandomVariableName (length: number = 6): string {
+        const rangeMinInteger: number = 10000,
+            rangeMaxInteger: number = 99999999;
+
+        return `_${Utils.hexadecimalPrefix}${(
+            Utils.decToHex(
+                RandomGeneratorUtils.getRandomInteger(rangeMinInteger, rangeMaxInteger)
+            )
+        ).substr(0, length)}`;
+    }
+
+    /**
+     * @param randomGeneratorSeed
+     */
+    public static setRandomGeneratorSeed (randomGeneratorSeed: number): void {
+        RandomGeneratorUtils.randomGenerator = new Chance(randomGeneratorSeed);
+    }
+}

+ 140 - 0
src/utils/Utils.ts

@@ -0,0 +1,140 @@
+import { JSFuck } from '../enums/JSFuck';
+
+const isEqual = require('is-equal');
+
+export class Utils {
+    /**
+     * @type {string}
+     */
+    public static readonly hexadecimalPrefix: string = '0x';
+
+    /**
+     * @param array
+     * @param searchElement
+     * @returns {boolean}
+     */
+    public static arrayContains (array: any[], searchElement: any): boolean {
+        return array.indexOf(searchElement) >= 0;
+    }
+
+    /**
+     * @param array
+     * @param times
+     * @returns {T[]}
+     */
+    public static arrayRotate <T> (array: T[], times: number): T[] {
+        if (!array.length) {
+            throw new ReferenceError(`Cannot rotate empty array.`);
+        }
+
+        if (times <= 0) {
+            return array;
+        }
+
+        let newArray: T[] = array,
+            temp: T | undefined;
+
+        while (times--) {
+            temp = newArray.pop()!;
+            newArray.unshift(temp);
+        }
+
+        return newArray;
+    }
+
+    /**
+     * @param dec
+     * @returns {string}
+     */
+    public static decToHex (dec: number): string {
+        const radix: number = 16;
+
+        return Number(dec).toString(radix);
+    }
+
+    /**
+     * @param url
+     * @returns {string}
+     */
+    public static extractDomainFromUrl (url: string): string {
+        let domain: string;
+
+        if (url.indexOf('://') > -1 || url.indexOf('//') === 0) {
+            domain = url.split('/')[2];
+        } else {
+            domain = url.split('/')[0];
+        }
+
+        domain = domain.split(':')[0];
+
+        return domain;
+    }
+
+    /**
+     * @param number
+     * @returns {boolean}
+     */
+    public static isInteger (number: number): boolean {
+        return number % 1 === 0;
+    }
+
+    /**
+     * @param map
+     * @param value
+     * @returns {any}
+     */
+    public static mapGetFirstKeyOf(map: Map <any, any>, value: any): any {
+        for (var [key, storageValue] of map) {
+            if (isEqual(value, storageValue)) {
+                return key;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @param obj
+     * @returns {T}
+     */
+    public static strEnumify <T extends {[prop: string]: ''|string}> (obj: T): T {
+        return obj;
+    }
+
+    /**
+     * @param string
+     * @returns {string}
+     */
+    public static stringToJSFuck (string: string): string {
+        return Array
+            .from(string)
+            .map((character: string): string => {
+                return JSFuck[character] || character;
+            })
+            .join(' + ');
+    }
+
+    /**
+     * @param string
+     * @returns {string}
+     */
+    public static stringToUnicodeEscapeSequence (string: string): string {
+        const radix: number = 16;
+
+        let prefix: string,
+            regexp: RegExp = new RegExp('[\x00-\x7F]'),
+            template: string;
+
+        return `${string.replace(/[\s\S]/g, (escape: string): string => {
+            if (regexp.test(escape)) {
+                prefix = '\\x';
+                template = '0'.repeat(2);
+            } else {
+                prefix = '\\u';
+                template = '0'.repeat(4);
+            }
+
+            return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
+        })}`;
+    }
+}

+ 4 - 4
test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts

@@ -2,7 +2,7 @@ import * as format from 'string-template';
 
 import { DomainLockNodeTemplate } from '../../../../../src/templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
 
-import { Utils } from '../../../../../src/Utils';
+import { CryptUtils } from '../../../../../src/utils/CryptUtils';
 
 
 const assert: Chai.AssertStatic = require('chai').assert;
@@ -46,7 +46,7 @@ describe('DomainLockNodeTemplate (): string', () => {
         [
             hiddenDomainsString,
             diff
-        ] = Utils.hideString(domainsString, domainsString.length * 3);
+        ] = CryptUtils.hideString(domainsString, domainsString.length * 3);
 
         assert.doesNotThrow(() => getFunctionFromTemplate({
             domainLockFunctionName: 'domainLockFunction',
@@ -62,7 +62,7 @@ describe('DomainLockNodeTemplate (): string', () => {
         [
             hiddenDomainsString,
             diff
-        ] = Utils.hideString(domainsString, domainsString.length * 3);
+        ] = CryptUtils.hideString(domainsString, domainsString.length * 3);
 
         assert.doesNotThrow(() => getFunctionFromTemplate({
             domainLockFunctionName: 'domainLockFunction',
@@ -78,7 +78,7 @@ describe('DomainLockNodeTemplate (): string', () => {
         [
             hiddenDomainsString,
             diff
-        ] = Utils.hideString(domainsString, domainsString.length * 3);
+        ] = CryptUtils.hideString(domainsString, domainsString.length * 3);
 
         assert.throws(() => getFunctionFromTemplate({
             domainLockFunctionName: 'domainLockFunction',

+ 3 - 3
test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts

@@ -6,7 +6,7 @@ import { StringArrayBase64DecodeNodeTemplate } from '../../../../../src/template
 import { StringArrayCallsWrapperTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
 import { StringArrayRc4DecodeNodeTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
 
-import { Utils } from '../../../../../src/Utils';
+import { CryptUtils } from '../../../../../src/utils/CryptUtils';
 
 const assert: Chai.AssertStatic = require('chai').assert;
 
@@ -26,7 +26,7 @@ function getFunctionFromTemplateBase64Encoding (
     let stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), templateData);
 
     return Function(`
-        var ${stringArrayName} = ['${Utils.btoa('test1')}'];
+        var ${stringArrayName} = ['${CryptUtils.btoa('test1')}'];
     
         ${stringArrayCallsWrapperTemplate}
         
@@ -52,7 +52,7 @@ function getFunctionFromTemplateRc4Encoding (
     let stringArrayCallsWrapperTemplate: string = format(StringArrayCallsWrapperTemplate(), templateData);
 
     return Function(`
-        var ${stringArrayName} = ['${Utils.btoa(Utils.rc4('test1', key))}'];
+        var ${stringArrayName} = ['${CryptUtils.btoa(CryptUtils.rc4('test1', key))}'];
     
         ${stringArrayCallsWrapperTemplate}
         

+ 6 - 4
test/index.spec.ts

@@ -7,16 +7,18 @@ BabelPolyfill.append();
 /**
  * Unit tests
  */
+import './unit-tests/ObfuscationResult.spec';
+import './unit-tests/OptionsNormalizer.spec';
+import './unit-tests/SourceMapCorrector.spec';
 import './unit-tests/cli/CLIUtils.spec';
 import './unit-tests/decorators/Initializable.spec';
 import './unit-tests/node/NodeAppender.spec';
 import './unit-tests/node/NodeUtils.spec';
-import './unit-tests/ObfuscationResult.spec';
-import './unit-tests/OptionsNormalizer.spec';
-import './unit-tests/SourceMapCorrector.spec';
 import './unit-tests/stack-trace-analyzer/StackTraceAnalyzer.spec';
 import './unit-tests/storages/ControlFlowStorage.spec';
-import './unit-tests/Utils.spec';
+import './unit-tests/utils/CryptUtils.spec';
+import './unit-tests/utils/RandomGeneratorUtils.spec';
+import './unit-tests/utils/Utils.spec';
 
 /**
  * Functional tests

+ 38 - 0
test/unit-tests/utils/CryptUtils.spec.ts

@@ -0,0 +1,38 @@
+import { CryptUtils } from '../../../src/utils/CryptUtils';
+
+const assert: Chai.AssertStatic = require('chai').assert;
+
+describe('CryptUtils', () => {
+    describe('btoa (string: string): string', () => {
+        it('should create a base-64 encoded string from a given string', () => {
+            assert.equal(CryptUtils.btoa('string'), 'c3RyaW5n');
+        });
+    });
+
+    describe('hideString (str: string, length: number): [string, string]', () => {
+        let original1: string = 'example.com',
+            [str1, diff] = CryptUtils.hideString(original1, 30);
+
+        it('should return a string with the original string within', () => {
+            assert.isTrue(str1.length > original1.length);
+            assert.equal(str1.replace(new RegExp('[' + diff + ']', 'g'), ''), original1);
+        });
+
+    });
+
+    describe('rc4 (string: string, key: string): string', () => {
+        it('should encode string using the rc4 algorithm', () => {
+            const string: string = 'test';
+            const key: string = 'key';
+
+            assert.notEqual(CryptUtils.rc4(string, key), string);
+        });
+
+        it('should encode and successfully decode string using the rc4 algorithm', () => {
+            const string: string = 'test';
+            const key: string = 'key';
+
+            assert.equal(CryptUtils.rc4(CryptUtils.rc4(string, key), key), string);
+        });
+    });
+});

+ 12 - 0
test/unit-tests/utils/RandomGeneratorUtils.spec.ts

@@ -0,0 +1,12 @@
+import { RandomGeneratorUtils } from '../../../src/utils/RandomGeneratorUtils';
+
+const assert: Chai.AssertStatic = require('chai').assert;
+
+describe('RandomGeneratorUtils', () => {
+    describe('getRandomVariableName (length: number = 6): string', () => {
+        it('should return a string of given length with random variable name', () => {
+            assert.match(RandomGeneratorUtils.getRandomVariableName(4), /^_0x(\w){4}$/);
+            assert.match(RandomGeneratorUtils.getRandomVariableName(6), /^_0x(\w){4,6}$/);
+        });
+    });
+});

+ 2 - 26
test/unit-tests/Utils.spec.ts → test/unit-tests/utils/Utils.spec.ts

@@ -1,6 +1,6 @@
-import { Utils } from '../../src/Utils';
+import { Utils } from '../../../src/utils/Utils';
 
-import { JSFuck } from '../../src/enums/JSFuck';
+import { JSFuck } from '../../../src/enums/JSFuck';
 
 const assert: Chai.AssertStatic = require('chai').assert;
 
@@ -35,12 +35,6 @@ describe('Utils', () => {
         });
     });
 
-    describe('btoa (string: string): string', () => {
-        it('should creates a base-64 encoded string from a given string', () => {
-            assert.equal(Utils.btoa('string'), 'c3RyaW5n');
-        });
-    });
-
     describe('decToHex (dec: number): string', () => {
         it('should creates a string with hexadecimal value from a given decimal number', () => {
             assert.equal(Utils.decToHex(0), '0');
@@ -60,13 +54,6 @@ describe('Utils', () => {
         });
     });
 
-    describe('getRandomVariableName (length: number = 6): string', () => {
-        it('should return a string of given length with random variable name', () => {
-            assert.match(Utils.getRandomVariableName(4), /^_0x(\w){4}$/);
-            assert.match(Utils.getRandomVariableName(6), /^_0x(\w){4,6}$/);
-        });
-    });
-
     describe('isInteger (number: number): boolean', () => {
         it('should return true if given number or string is integer', () => {
             assert.equal(Utils.isInteger(4), true);
@@ -118,15 +105,4 @@ describe('Utils', () => {
             assert.equal(Utils.stringToUnicodeEscapeSequence('string'), expected);
         });
     });
-
-    describe('hideString (str: string, length: number): [string, string]', () => {
-        let original1: string = 'example.com',
-            [str1, diff] = Utils.hideString(original1, 30);
-
-        it('should return a string with the original string within', () => {
-            assert.isTrue(str1.length > original1.length);
-            assert.equal(str1.replace(new RegExp('[' + diff + ']', 'g'), ''), original1);
-        });
-
-    });
 });

Vissa filer visades inte eftersom för många filer har ändrats