JvavScript
JvavScript是我提出的一个基于JavaScript的深奥编程语言,是JavaScript的一个子集,也是JSFuck的一个超集。JvavScript代码符合JavaScript表达式的语法,然而只能使用有限的几种字符:
( ) [ ] < > + - ! , = ? : _ $
并且为了使代码稍简洁些,定义了几个常量:
const _ = alert, __ = prompt, $ = String.fromCharCode, $$ = this;
JSFuck基本混淆手法
值 | JSFuck |
---|---|
"" |
+[] |
false |
![] |
true |
!![] 或 !+[] |
0 |
+![] |
1 |
+!![] 或 +!+[] |
Hello world
_($(
+!+[]+[]+(+[])-(+!+[]+!+[]+!+[])+[]+(+!+[]+!+[]),
+!+[]+[]+(+[])+(+!+[]),
+!+[]+[]+(+[])+(+!+[]+[]+(+[])-(+!+[]+!+[])),
+!+[]+[]+(+[])+(+!+[]+[]+(+[])-(+!+[]+!+[])),
+!+[]+[]+(+!+[])+(+!+[]),
+!+[]+!+[]+!+[]+!+[]+[]+(+!+[]+!+[]+!+[]+!+[]),
+!+[]+!+[]+!+[]+[]+(+!+[]+!+[]),
+!+[]+[]+(+!+[])+(+!+[]+[]+(+[])-!+[]),
+!+[]+[]+(+!+[])+(+!+[]),
+!+[]+[]+(+!+[])+(+!+[]+!+[]+!+[]+!+[]),
+!+[]+[]+(+[])+(+!+[]+[]+(+[])-(+!+[]+!+[])),
+!+[]+[]+(+[])+(+[]),
+!+[]+!+[]+!+[]+[]+(+!+[]+!+[]+!+[])
))
运行以上代码会输出
Hello, world!
以上代码的实质:
alert(String.fromCharCode(
1 + "" + 0 - (1 + true + true) + "" + (1 + true), // "72"
1 + "" + 0 + 1, // "101"
1 + "" + 0 + (1 + "" + 0 - (1 + true)), // "108"
1 + "" + 0 + (1 + "" + 0 - (1 + true)), // "108"
1 + "" + 1 + 1, // "111"
1 + true + true + true + "" + (1 + true + true + true), // "44"
1 + true + true + "" + (1 + true), // "32"
1 + "" + 1 + (1 + "" + 0 - true), // "119"
1 + "" + 1 + 1, // "111"
1 + "" + 1 + (1 + true + true + true), // "114"
1 + "" + 0 + (1 + "" + 0 - (1 + true)), // "108"
1 + "" + 0 + 0, // "100"
1 + true + true + "" + (1 + true + true) // "33"
))
brainfuck解释器
为了证明JvavScript不用太多地依赖JSFuck编码JavaScript源代码也能做到图灵完备,我写了一个brainfuck解释器:
_((($_,_$$,__$)=>$_($_,_$$,+[],__$,+[],[]+[],[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()(([][[]]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[!+[]+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]])+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])+[])[+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(+[]+[][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+!+[]]+(![]+[])[+!+[]]+(+[![]]+[+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[!+[]+!+[]+!+[]]+[+[]]+[+[]]+[+[]]+[+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]]),+[]))(($_,_$$,_$$_,__$,__$_,$$_,$__,$__$)=>(
_$$[_$$_]?
_$$[_$$_]==([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+[]]?
$_($_,_$$,_$$_+!![],__$,__$_,$$_,$__,$__$?$__$-!![]:!![]+!![]+!![]+[]+(+[])+(+[])+(+[])+(+[])-!![])
:_$$[_$$_]==([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[!+[]+!+[]]?
$_($_,_$$,_$$_+!![],__$,__$_,$$_,$__,$__$==!![]+!![]+!![]+[]+(+[])+(+[])+(+[])+(+[])-!![]?+[]:$__$+!![])
:(
_$$[_$$_]==(+((+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]+[+[]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+!+[]]])+[])[!+[]+!+[]]?
($__[$__$]--,[])
:_$$[_$$_]==(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[!+[]+!+[]]?
($__[$__$]++,[])
:_$$[_$$_]==(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]?
($$_+=$($__[$__$]),[])
:_$$[_$$_]==[[]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]([[]])+[]?
($__[$__$]=__$[__$_]?__$[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(+(+!+[]+[+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+[+!+[]])[+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+!+[]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]])()(([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]())[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(+[]+[][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+[]]](__$_++):-!![],[])
:[][[]]
)?
$_($_,_$$,_$$_+!![],__$,__$_,$$_,$__,$__$)
:_$$[_$$_]==([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[+[]]?
$_($_,_$$,$__[$__$]?_$$_+!![]:(($_$,_$$,_$$_)=>$_$($_$,_$$,_$$_,+[]))(($_$,_$$,_$$_,_$)=>(
_$$[_$$_]?
_$$[_$$_]==([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[+[]]?
$_$($_$,_$$,_$$_+!![],_$+!![])
:_$$[_$$_]==([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[!+[]+!+[]+[!+[]+!+[]]]?
_$?$_$($_$,_$$,_$$_+!![],_$-!![]):_$$_+!![]
:$_$($_$,_$$,_$$_+!![],_$)
:_$$_
),_$$,_$$_+!![]),__$,__$_,$$_,$__,$__$)
:_$$[_$$_]==([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[!+[]+!+[]+[!+[]+!+[]]]?
$_($_,_$$,$__[$__$]?(($_$,_$$,_$$_)=>$_$($_$,_$$,_$$_,+[]))(($_$,_$$,_$$_,_$)=>(
_$$[_$$_]?
_$$[_$$_]==([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[!+[]+!+[]+[!+[]+!+[]]]?
$_$($_$,_$$,_$$_-!![],_$+!![])
:_$$[_$$_]==([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[+[]]?
_$?$_$($_$,_$$,_$$_-!![],_$-!![]):_$$_+!![]
:$_$($_$,_$$,_$$_-!![],_$)
:+[]
),_$$,_$$_-!![]):_$$_+!![],__$,__$_,$$_,$__,$__$)
:$_($_,_$$,_$$_+!![],__$,__$_,$$_,$__,$__$)
:$$_
),__(([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]),__(([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+([][[]]+[])[+[]]+(!![]+[])[+[]])))
由于用递归代替循环,所以太过复杂的brainfuck代码可能会无法执行,比如目前最短的Hello world:
+[-->-[>>+>-----<<]<--<---]>-.>>>+.>>..+++[.>]<<<<.+++.------.<<-.>>>>+.
它在我的浏览器上会报错(递归次数过多)。不过,这个Hello world在我的浏览器上可以运行:
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
代码中时常出现的大段只由 ()+[]!
组成的部分,是用JSFuck编码的字符串。(还有一个表达式 new Int8Array(30000)
也是用JSFuck编码的。)
未经混淆的JavaScript源代码:
alert(((func, code, input) => func(func, code, 0, input, 0, "", new Int8Array(30000), 0))((func, code, codePointer, input, inputPointer, output, memory, memoryPointer) => (
code[codePointer] ?
code[codePointer] == "<" ?
func(func, code, codePointer + 1, input, inputPointer, output, memory, memoryPointer ? memoryPointer - 1 : 29999)
: code[codePointer] == ">" ?
func(func, code, codePointer + 1, input, inputPointer, output, memory, memoryPointer==29999 ? 0 : memoryPointer + 1)
: (
code[codePointer] == "-" ?
(memory[memoryPointer]--, 1)
: code[codePointer] == "+" ?
(memory[memoryPointer]++, 1)
: code[codePointer] == "." ?
(output += String.fromCharCode(memory[memoryPointer]), 1)
: code[codePointer] == ", " ?
(memory[memoryPointer] = input[inputPointer] ? input.charCodeAt(inputPointer++) : -1, 1)
: undefined
) ?
func(func, code, codePointer + 1, input, inputPointer, output, memory, memoryPointer)
: code[codePointer] == "[" ?
func(func, code, memory[memoryPointer] ? codePointer + 1 : ((func2, code, codePointer) => func2(func2, code, codePointer, 0))((func2, code, codePointer, count) => (
code[codePointer] ?
code[codePointer] == "[" ?
func2(func2, code, codePointer + 1, count + 1)
: code[codePointer] == "]" ?
count ? func2(func2, code, codePointer + 1, count-1) : codePointer + 1
: func2(func2, code, codePointer + 1, count)
: codePointer
), code, codePointer + 1), input, inputPointer, output, memory, memoryPointer)
: code[codePointer] == "]" ?
func(func, code, memory[memoryPointer] ? ((func2, code, codePointer) => func2(func2, code, codePointer, 0))((func2, code, codePointer, count) => (
code[codePointer] ?
code[codePointer] == "]" ?
func2(func2, code, codePointer-1, count + 1)
: code[codePointer] == "[" ?
count ? func2(func2, code, codePointer-1, count-1) : codePointer + 1
: func2(func2, code, codePointer-1, count)
: 0
), code, codePointer - 1) : codePointer + 1, input, inputPointer, output, memory, memoryPointer)
: func(func, code, codePointer + 1, input, inputPointer, output, memory, memoryPointer)
: output
), prompt("code"), prompt("input")))
2022-12-04 更新(写于 2022-11-13)
前几天翻看本页时,发现上述 brainf 解释器代码中用 JSFuck 编码的部分太长,可以大幅优化。如表达式 new Int8Array(30000)
被表示为 Function("return eval")()("new Int8Array(30000)")
,其中 Function
构造函数来自 []["flat"]["constructor"]
,且完全没有使用 JvavScript 中定义的常量;应当使用 $$["eval"]("new Int8Array(30000)")
代替。
随后我萌生了一个想法,即编写一个程序来找出用尽可能短的 JvavScript 表达式来获得任意的双精度浮点数或字符串值的方法。
JvavScript 中存在比 []
更短的真值($
或 _
),而且允许减号,因此很多基本值的编码结果会比 JSFuck 更短:
值 | JSFuck | JvavScript |
---|---|---|
false |
![] |
!_ |
true |
!+[] |
!!_ |
1 |
+!+[] |
+!!_ |
"10" |
+!+[]+[+[]] |
[+!!_]+-[] |
7 |
!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[] |
[+!!_]+-[]-!!_-!!_-!!_ |
语法比 JSFuck 更丰富的代价是,要找到最佳的编码方案变得极为困难。用 "10"
减去 3 个 true
(22 字节)要比 7 个 true
相加(27 字节)短许多,这一点尚且比较容易确定;若是数字稍大一些,恐怕情况会变得极其复杂。譬如编码数字 179:
方案 | JvavScript | 长度 (字节) |
---|---|---|
+("1" + "7" + "9") |
+(+!!_+[[+!!_]+-[]-!!_-!!_-!!_]+[[+!!_]+-[]-!!_]) |
49 |
+("17" + "9") |
+([!!_+!!_]+-[]-!!_-!!_-!!_+[[+!!_]+-[]-!!_]) |
45 |
200 - 21 |
[!!_+!!_]+-[]+-[]-(!!_+!!_+[+!!_]) |
34 |
180 - 1 |
+!!_+[[+!!_]+-[]-!!_-!!_]+-[]-!!_ |
33 |
本着知难而进的精神,我成功写出了一个懂得减法的数字编码程序(源代码),可以编码任意双精度浮点数,只是在特定情况下长度可能并不是最优。
正当我信心满满朝着字符串进军时,未曾设想的情况出现了。一部分字符除了可以通过字符编码获得外,还可以通过其他方式获得(如 (false + [])[0]
返回 "f"
),我称之为“简单编码”。在众多选择的排列组合中找到最短方案不是一件容易的事。有的字符如果单独出现,用简单编码更短;但如果夹在两个字符编码之间,则不如也用字符编码,这样就可以省去一套函数名、函数调用的括号和两个加号 )+
+$(
,只在两边用逗号分隔。下面的图示展示了编码字符串 "Hello"
的多种可行思路:
另外,当字符串恰好包含一些简单值(如 false
)的字符串形式时也可以将简单值整个嵌入进去;数字还可以通过减法获得。要想找出最短的编码方式,就需要在类似上图甚至更复杂的路线图中找出最佳的路线,我判断这对于编码一个字符串来说要求过高了。因此最后我决定采取最通用的方法,只使用 String.fromCharCode()
来获得字符串。
回到 brainf 解释器的问题上。为了体现 JvavScript 不需要 eval()
或 Function()
也能活得好好的(草),我们使用反射(en)来调用构造函数 Int8Array
:
$$["Reflect"]["construct"]($$["Int8Array"], [30000])
代码中还用到了几个字符串,它们也可以使用字符编码来获得。下面是修改后的代码。
_((($_,_$$,__$)=>$_($_,_$$,+[],__$,+[],[]+[],$$[$([+!!_]+-[]-!!_-!!_+[!!_+!!_],[+!!_]+-[]+(+!!_),[+!!_]+-[]+(!!_+!!_),+!!_+[+!!_]+-[]-!!_-!!_,[+!!_]+-[]+(+!!_),[+!!_]+-[]+-[]-!!_,+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_))][$([+!!_]+-[]+-[]-!!_,+!!_+[+!!_]+(+!!_),+!!_+[+!!_]+-[],+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_),+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_),+!!_+[+!!_]+(!!_+!!_+!!_+!!_),+!!_+[!!_+!!_]+-[]-!!_-!!_-!!_,[+!!_]+-[]+-[]-!!_,+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_))]($$[$([+!!_]+-[]-!!_-!!_-!!_+[!!_+!!_+!!_],+!!_+[+!!_]+-[],+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_),!!_+!!_+!!_+!!_+!!_+[!!_+!!_+!!_+!!_+!!_+!!_],!!_+!!_+!!_+!!_+!!_+!!_+[!!_+!!_+!!_+!!_+!!_],+!!_+[+!!_]+(!!_+!!_+!!_+!!_),+!!_+[+!!_]+(!!_+!!_+!!_+!!_),[+!!_]+-[]+-[]-!!_-!!_-!!_,+!!_+[!!_+!!_]+(+!!_))],[[!!_+!!_+!!_]+-[]+-[]+-[]+-[]]),+[]))(($_,_$$,_$$_,__$,__$_,$$_,$__,$__$)=>(
_$$[_$$_]?
_$$[_$$_]==$([!!_+!!_+!!_+!!_+!!_+!!_]+-[])?
$_($_,_$$,_$$_+!!_,__$,__$_,$$_,$__,$__$?$__$-!!_:[!!_+!!_+!!_]+-[]+-[]+-[]+-[]-!!_)
:_$$[_$$_]==$(!!_+!!_+!!_+!!_+!!_+!!_+[!!_+!!_])?
$_($_,_$$,_$$_+!![],__$,__$_,$$_,$__,$__$==[!!_+!!_+!!_]+-[]+-[]+-[]+-[]-!!_?+[]:$__$+!!_)
:(
_$$[_$$_]==(-!!_+[])[+[]]?
($__[$__$]--,!!_)
:_$$[_$$_]==$(!!_+!!_+!!_+!!_+[!!_+!!_+!!_])?
($__[$__$]++,!!_)
:_$$[_$$_]==$(!!_+!!_+!!_+!!_+[!!_+!!_+!!_+!!_+!!_+!!_])?
($$_+=$($__[$__$]),!!_)
:_$$[_$$_]==$(!!_+!!_+!!_+!!_+[!!_+!!_+!!_+!!_])?
($__[$__$]=__$[__$_]?__$[$([+!!_]+-[]+-[]-!!_,[+!!_]+-[]+(!!_+!!_+!!_+!!_),[+!!_]+-[]+-[]-!!_-!!_-!!_,+!!_+[+!!_]+(!!_+!!_+!!_+!!_),[+!!_]+-[]+-[]-(!!_+!!_+!!_+[!!_+!!_+!!_]),+!!_+[+!!_]+(+!!_),[+!!_]+-[]+-[],[+!!_]+-[]+(+!!_),!!_+!!_+!!_+!!_+!!_+!!_+[!!_+!!_+!!_+!!_+!!_],+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_))](__$_++):-!!_,!!_)
:!_
)?
$_($_,_$$,_$$_+!!_,__$,__$_,$$_,$__,$__$)
:_$$[_$$_]==$([+!!_]+-[]-!!_+[+!!_])?
$_($_,_$$,$__[$__$]?_$$_+!!_:(($_$,_$$,_$$_)=>$_$($_$,_$$,_$$_,+[]))(($_$,_$$,_$$_,_$)=>(
_$$[_$$_]?
_$$[_$$_]==$([+!!_]+-[]-!!_+[+!!_])?
$_$($_$,_$$,_$$_+!![],_$+!!_)
:_$$[_$$_]==$([+!!_]+-[]-!!_+[!!_+!!_+!!_])?
_$?$_$($_$,_$$,_$$_+!!_,_$-!!_):_$$_+!!_
:$_$($_$,_$$,_$$_+!!_,_$)
:_$$_
),_$$,_$$_+!!_),__$,__$_,$$_,$__,$__$)
:_$$[_$$_]==$([+!!_]+-[]-!!_+[!!_+!!_+!!_])?
$_($_,_$$,$__[$__$]?(($_$,_$$,_$$_)=>$_$($_$,_$$,_$$_,+[]))(($_$,_$$,_$$_,_$)=>(
_$$[_$$_]?
_$$[_$$_]==$([+!!_]+-[]-!!_+[!!_+!!_+!!_])?
$_$($_$,_$$,_$$_-!!_,_$+!!_)
:_$$[_$$_]==$([+!!_]+-[]-!!_+[+!!_])?
_$?$_$($_$,_$$,_$$_-!![],_$-!!_):_$$_+!!_
:$_$($_$,_$$,_$$_-!!_,_$)
:+[]
),_$$,_$$_-!!_):_$$_+!!_,__$,__$_,$$_,$__,$__$)
:$_($_,_$$,_$$_+!!_,__$,__$_,$$_,$__,$__$)
:$$_
),__($([+!!_]+-[]+-[]-!!_,+!!_+[+!!_]+(+!!_),[+!!_]+-[]+-[],[+!!_]+-[]+(+!!_))),__($([+!!_]+-[]+(!!_+!!_+!!_+!!_+!!_),+!!_+[+!!_]+-[],+!!_+[+!!_]+(!!_+!!_),+!!_+[!!_+!!_]+-[]-!!_-!!_-!!_,+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_)))))
以上 brainf 实现中,EOF 后再读取输入会返回 -1。若要让 EOF 不改变当前单元格值可将这行代码
($__[$__$]=__$[__$_]?__$[$([+!!_]+-[]+-[]-!!_,[+!!_]+-[]+(!!_+!!_+!!_+!!_),[+!!_]+-[]+-[]-!!_-!!_-!!_,+!!_+[+!!_]+(!!_+!!_+!!_+!!_),[+!!_]+-[]+-[]-(!!_+!!_+!!_+[!!_+!!_+!!_]),+!!_+[+!!_]+(+!!_),[+!!_]+-[]+-[],[+!!_]+-[]+(+!!_),!!_+!!_+!!_+!!_+!!_+!!_+[!!_+!!_+!!_+!!_+!!_],+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_))](__$_++):-!!_,!!_)
替换为
(__$[__$_]?($__[$__$]=__$[$([+!!_]+-[]+-[]-!!_,[+!!_]+-[]+(!!_+!!_+!!_+!!_),[+!!_]+-[]+-[]-!!_-!!_-!!_,+!!_+[+!!_]+(!!_+!!_+!!_+!!_),[+!!_]+-[]+-[]-(!!_+!!_+!!_+[!!_+!!_+!!_]),+!!_+[+!!_]+(+!!_),[+!!_]+-[]+-[],[+!!_]+-[]+(+!!_),!!_+!!_+!!_+!!_+!!_+!!_+[!!_+!!_+!!_+!!_+!!_],+!!_+[+!!_]+(!!_+!!_+!!_+!!_+!!_+!!_))](__$_++)):_,!!_)
或者若需要 EOF 返回 0,可将前者中的“:-!!_
”改为“:+[]
”。
若要在运行完成后输出整个内存纸带中的值,可将倒数第二行“:$$_
”替换为“:(_($__),$$_)
”。
尽管修改后的 brainf 解释器代码更短了,但调用堆栈溢出的问题还没有解决,稍微长一点的循环就会让解释器报错。这一点理论上应该可以优化,但是我懒得弄了。就这样吧。
顺带补充一下对于四个预定义常量的规定,之前的说明并不够清楚。
_
函数接受一个参数,默认值为空字符串,将该参数的内容以字符串形式输出。输出到终端时,末尾应添加换行符。返回undefined
。__
函数接受两个参数message
和defaultValue
。若message
不为undefined
则仿照_
函数的方法输出message
,然后要求一行输入,若defaultValue
不为undefined
,则以其字符串形式作为输入框的初始内容。返回一个字符串,不包含末尾的换行符(如果有),但如果用户取消输入或 EOF,则应返回null
。$
函数在被调用时的行为必须与String.fromCharCode()
相同。$$
对象必须是当前环境下的全局作用域。
对于这四个函数或对象转换成字符串的结果不再做要求。对这些常量赋值的效果是未定义的,因此它们可以实际上不是常量。
另外,JvavScript 并没有允许代码包含空白字符,但一般为了可读性(大嘘)还是需要使用一定的换行和缩进。现规定空白字符只能在不影响语法的情况下使用,即删去所有空白后代码的含义必须与原来一致。如“[-!!_]+ +!!_
”是不允许的,因为删去空格后两个加号会变成一个递增操作符,导致语法错误;需要改成“-!!_+[+!!_]
”。这也意味着不可以用换行来代替分号。
一个按照上述规定运行 JvavScript 代码的函数:
function executeJvavScript(code) {
var match = code.match(/[^()[\]<>+\-!,=?:_$\s]/)
if (match)
throw new SyntaxError(`Code contains invalid character ‘${match[0]}’`)
code = code.replace(/\s+/g, "")
var fun = new Function("_", "__", "$", "$$", code)
fun(alert, prompt, String.fromCharCode, self)
}