javascript-obfuscator
Version:
JavaScript obfuscator
143 lines (115 loc) • 4.34 kB
text/typescript
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { ICryptUtils } from '../interfaces/utils/ICryptUtils';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { RandomGenerator } from './RandomGenerator';
import { Utils } from './Utils';
()
export class CryptUtils implements ICryptUtils {
/**
* @type {IRandomGenerator}
*/
private readonly randomGenerator: IRandomGenerator;
/**
* @param {IRandomGenerator} randomGenerator
*/
public constructor (
randomGenerator: IRandomGenerator
) {
(ServiceIdentifiers.IRandomGenerator) this.randomGenerator = randomGenerator;
}
/**
* @param {string} string
* @returns {string}
*/
public btoa (string: string): string {
const chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let output: string = '';
string = encodeURIComponent(string).replace(/%([0-9A-F]{2})/g, (match: string, p1: string) => {
return String.fromCharCode(parseInt(`${Utils.hexadecimalPrefix}${p1}`, 16));
});
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 = <number>block << 8 | charCode;
}
return output;
}
/**
* Hides string inside a other random string with larger length
*
* @param {string} str
* @param {number} length
* @returns {[string , string]}
*/
public hideString (str: string, length: number): [string, string] {
const escapeRegExp: (s: string) => string = (s: string) =>
s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
const randomMerge: (s1: string, s2: string) => string = (s1: string, s2: string): string => {
let i1: number = -1;
let i2: number = -1;
let result: string = '';
while (i1 < s1.length || i2 < s2.length) {
if (this.randomGenerator.getMathRandom() < 0.5 && i2 < s2.length) {
result += s2.charAt(++i2);
} else {
result += s1.charAt(++i1);
}
}
return result;
};
const randomString: string = this.randomGenerator.getRandomGenerator().string({
length: length,
pool: RandomGenerator.randomGeneratorPool
});
let randomStringDiff: string = randomString.replace(
new RegExp(`[${escapeRegExp(str)}]`, 'g'),
''
);
const randomStringDiffArray: string[] = randomStringDiff.split('');
this.randomGenerator.getRandomGenerator().shuffle(randomStringDiffArray);
randomStringDiff = randomStringDiffArray.join('');
return [randomMerge(str, randomStringDiff), randomStringDiff];
}
/**
* RC4 symmetric cipher encryption/decryption
* https://gist.github.com/farhadi/2185197
*
* @param {string} string
* @param {string} key
* @returns {string}
*/
public rc4 (string: string, key: string): string {
const s: number[] = [];
let j: number = 0;
let x: number;
let result: string = '';
// eslint-disable-next-line no-var
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;
}
}