UNPKG

js-confuser

Version:

JavaScript Obfuscation Tool.

117 lines (95 loc) 3.02 kB
import { ok } from "assert"; import { ObfuscateOptions } from "../options"; import { alphabeticalGenerator, createZeroWidthGenerator } from "./gen-utils"; import { choice, getRandomChineseString, getRandomHexString, getRandomInteger, } from "./random-utils"; import { reservedKeywords, reservedObjectPrototype } from "../constants"; import Obfuscator from "../obfuscator"; /** * Generate random names for variables and properties. */ export class NameGen { public generatedNames = new Set<string>(); public notSafeForReuseNames = new Set<string>(); private counter = 1; private zeroWidthGenerator = createZeroWidthGenerator(); constructor( private identifierGenerator: ObfuscateOptions["identifierGenerator"] = "randomized", public options = { avoidReserved: false, avoidObjectPrototype: false, } ) {} private attemptGenerate() { if (typeof this.identifierGenerator === "function") { var value = this.identifierGenerator(); ok( typeof value === "string", "Custom identifier generator must return a string" ); return value; } var mode = Obfuscator.prototype.computeProbabilityMap( this.identifierGenerator ); const randomizedLength = getRandomInteger(6, 8); switch (mode) { case "randomized": var characters = "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""); var numbers = "0123456789".split(""); var combined = [...characters, ...numbers]; var result = ""; for (var i = 0; i < randomizedLength; i++) { result += choice(i == 0 ? characters : combined); } return result; case "hexadecimal": return "_0x" + getRandomHexString(randomizedLength); case "mangled": var mangledName = ""; do { mangledName = alphabeticalGenerator(this.counter++); } while (reservedKeywords.includes(mangledName)); return mangledName; case "number": return "var_" + this.counter++; case "zeroWidth": return this.zeroWidthGenerator.generate(); case "chinese": return getRandomChineseString(randomizedLength); default: throw new Error( "Invalid identifier generator mode: " + this.identifierGenerator ); } } generate(isSafeForReuse = true): string { let name: string; do { name = this.attemptGenerate(); // Avoid reserved keywords if (this.options.avoidReserved && reservedKeywords.includes(name)) { name = ""; continue; } // Avoid reserved object prototype properties if ( this.options.avoidObjectPrototype && reservedObjectPrototype.has(name) ) { name = ""; continue; } } while (!name || this.generatedNames.has(name)); this.generatedNames.add(name); if (!isSafeForReuse) { this.notSafeForReuseNames.add(name); } return name; } }