Last active
December 12, 2022 10:01
-
-
Save cflems/f1d9d5566f8fa05be17b8e554615baa1 to your computer and use it in GitHub Desktop.
Obfuscate JavaScript code into having zero readable characters; I want to improve this not to use eval at all but I'll have to write a JS tokenizer for that.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const zero = '+[]'; // 1 | |
const one = '+!![]'; // 1 | |
const two = '('+ one + one +')'; // 2 | |
const three = '('+ one + one + one +')'; // 3 | |
const four = '('+ one + one + '<<' + one +')'; // 3 | |
const five = '('+ four + one +')'; // 4 | |
const six = '('+ one + one + one + '<<' + one +')'; // 4 | |
const seven = '('+ six + one +')'; | |
const eight = '('+ one + one + '<<' + one + one +')'; // 4 | |
const int_lits = {0: zero, 1: one, 2: two, 3: three, 4: four, 5: five, 6: six, 7: seven, 8: eight}; | |
function compile_int(n) { | |
if (n in int_lits) return int_lits[n]; | |
let compiled = [], m = n; | |
if (n < 0) m = -n; | |
const stack = m.toString(8).split(''); | |
for (let sh = 0; stack.length > 0; sh++) { | |
const lit = parseInt(stack.pop()); | |
if (lit === 0) continue; | |
let tentative = int_lits[lit]; | |
if (sh > 0) tentative = '('+tentative+'<<'+compile_int(sh*3)+')'; | |
compiled.push(tentative); | |
} | |
compiled = '('+compiled.join('|')+')'; | |
if (n < 0) compiled = '-'+compiled; | |
int_lits[n] = compiled; | |
return compiled; | |
} | |
const char_lits = { | |
'N': '(+{}+[])['+compile_int(0)+']', | |
'a': '(+{}+[])['+compile_int(1)+']', | |
// N | |
'[': '({}+[])['+compile_int(0)+']', | |
'o': '({}+[])['+compile_int(1)+']', | |
'b': '({}+[])['+compile_int(2)+']', | |
'j': '({}+[])['+compile_int(3)+']', | |
// e | |
'c': '({}+[])['+compile_int(5)+']', | |
// t | |
' ': '({}+[])['+compile_int(7)+']', | |
'O': '({}+[])['+compile_int(8)+']', | |
// bject | |
']': '({}+[])['+compile_int(14)+']', | |
'f': '(![]+[])['+compile_int(0)+']', | |
// a | |
'l': '(![]+[])['+compile_int(2)+']', | |
's': '(![]+[])['+compile_int(3)+']', | |
// e | |
't': '(!![]+[])['+compile_int(0)+']', | |
'r': '(!![]+[])['+compile_int(1)+']', | |
'u': '(!![]+[])['+compile_int(2)+']', | |
'e': '(!![]+[])['+compile_int(3)+']', | |
'\/': '(/\\\\/+[])['+compile_int(0)+']', | |
'\\': '(/\\\\/+[])['+compile_int(1)+']', | |
'I': '((+!![]/+[])+[])['+compile_int(0)+']', | |
'n': '((+!![]/+[])+[])['+compile_int(1)+']', | |
// f | |
'i': '((+!![]/+[])+[])['+compile_int(3)+']', | |
// nit | |
'y': '((+!![]/+[])+[])['+compile_int(7)+']', | |
//un | |
'd': '([]['+compile_int(0)+']+[])['+compile_int(2)+']', | |
// efined | |
}; | |
// wanted: m C h in relatively short fashion | |
function compile_string(s, as_code = false) { | |
const compiled = []; | |
for (const c of s) { | |
const req = '$('+compile_int(c.charCodeAt(0))+')'; | |
if (c in char_lits && (char_lits[c].length <= req.length || !as_code)) | |
compiled.push(char_lits[c]); | |
else | |
compiled.push(req); | |
} | |
return compiled.join('+'); | |
} | |
// these are ~300 chars, will require compression | |
char_lits['p'] = '(/</['+compile_string('constructor')+']+[])['+compile_int(14)+']'; | |
char_lits['S'] = '([]+([]+[])['+compile_string('constructor')+'])['+compile_int(9)+']'; | |
char_lits['g'] = '([]+([]+[])['+compile_string('constructor')+'])['+compile_int(14)+']'; | |
char_lits['('] = '([]+([]+[])['+compile_string('constructor')+'])['+compile_int(15)+']'; | |
char_lits[')'] = '([]+([]+[])['+compile_string('constructor')+'])['+compile_int(16)+']'; | |
char_lits['{'] = '([]+([]+[])['+compile_string('constructor')+'])['+compile_int(18)+']'; | |
char_lits['}'] = '([]+([]+[])['+compile_string('constructor')+'])['+compile_int(34)+']'; | |
char_lits['v'] = '([]+([]+[])['+compile_string('constructor')+'])['+compile_int(25)+']'; | |
char_lits['m'] = '((+[])['+compile_string('constructor')+']+[])['+compile_int(11)+']'; | |
// these are ~800 chars, will require great compression | |
char_lits['h'] = '('+compile_int(17)+')['+compile_string('toString')+']('+compile_int(24)+')'; | |
char_lits['C'] = '((()=>{})['+compile_string('constructor')+']('+compile_string('return escape')+')()('+compile_string('\\')+'))['+compile_int(2)+']'; | |
const prelude = '$=([]+[])['+compile_string('constructor')+']['+compile_string('fromCharCode')+'];'; | |
function compile_code(code) { | |
return prelude + '(()=>{})['+compile_string('constructor')+']('+compile_string(code, true)+')()'; | |
} | |
if (typeof process === 'undefined') | |
process = global.process; | |
if (process.argv.length < 3) { | |
console.log('Usage:', process.argv[0], process.argv[1], '<input file>'); | |
process.exit(1); | |
} | |
if (process.argv[2] === '-') { | |
const data = []; | |
process.stdin.on('data', function (fragment) { | |
data.push(fragment); | |
}); | |
process.stdin.on('close', function() { | |
const code = Buffer.concat(data).toString(); | |
console.log(compile_code(code)); | |
}); | |
} else { | |
if (typeof require === 'undefined') | |
require = global.require || global.process.mainModule.constructor._load; | |
const fs = require('fs'); | |
const code = fs.readFileSync(process.argv[2], {encoding: 'utf8'}); | |
console.log(compile_code(code)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment