JavaScript で記号プログラミング
JavaScript も他の言語と同様に記号($=_-+~[]{}()*/<!\;"',.
)のみを使ったプログラミングが可能です。
以下に console.log("Hello World") を実行するための手順を説明します。
コードに出てくる $0 や $a などの変数は、読者への説明のために可読性のある形で記述しています。
もちろん、これらの変数は記号のみを使った形に書き下すことが可能です。
-
まずは記号から数値を導出します。
$0 = +[]; // 0 (-[] or +"") でも可能 $1 = -~[]; // 1 $2 = $1+$1; // 2 (1+1) $3 = $2+$1; // 3 (2+1) $4 = $3+$1; // 4 (3+1) $5 = $4+$1; // 5 (4+1) $6 = $3<<$1; // 6 (3<<1) $7 = $6+$1; // 7 (6+1) $8 = $2<<$2; // 8 (2<<2) $9 = $3*$3; // 9 (3*3) $10 = $5<<$1; // 10 (5<<1)
-
Generic Object( Object,Array,String,Number,RegExp ) の文字列表現から、様々な文字を取得します。
$Object = ""+{}; // "[object Object]" $false = ""+![]; // "false" $true = ""+!![]; // "true" $undefined = ""+[][[]]; // "undefined" $c = $Object[$5]; $n = $undefined[$1]; $o = $Object[$1]; $r = $true[$1]; $s = $false[$3] $t = $true[$0]; $u = $undefined[$0]; $constructor = $c + $o + $n + $s + $t + $r + $u + $c + $t + $o + $r; $Array = ""+([][$constructor]); // "function Array() { [native code] }" $String = ""+(""[$constructor]); // "function String() { [native code] }" $RegExp = ""+(/ /[$constructor]); // "function RegExp() { [native code] }" $Number = ""+($0)[$constructor]; // "function Number() { [native code] }" $Infinity = ""+($1/$0); // "Infinity" $NaN = ""+(+{}); // "NaN" $a = $false[$1]; $b = $Object[$2]; $d = $undefined[$2]; $e = $true[$3]; $f = $false[$0]; $g = $RegExp[$10+$1]; $i = $Infinity[$3]; $j = $Object[$3]; $l = $false[$2]; $m = $Number[$10+$1]; $p = $RegExp[$10+$4]; $v = $RegExp[$10+$10+$5] $x = $RegExp[$10+$3] $y = $Infinity[$7]; $A = $Array[$9]; $E = $RegExp[$10+$2]; $I = $Infinity[$0]; $N = $Number[$0]; $O = $Object[$8]; $R = $RegExp[$9]; $S = $String[$9];
-
new Function を合成します。ここから先は $fn(...) で関数呼び出しが可能になります。
$return = $r + $e + $t + $u + $r + $n; $self = $s + $e + $l + $f; $FunctionObject = ""[$constructor][$constructor] // function Function() { [native code] } -> new Function() $fn = $FunctionObject;
-
Window Object への参照を獲得します。
$WindowObject = $fn(($return+" "+$self))(); // new Function("return self")() -> [Object Window] $Window = ""+$WindowObject; // "[object Window]" $W = $Window[$8]; $w = $Window[$10+$3];
-
JavaScript の16進表現(\xnn)を使って "h" と "C" を獲得し、String.fromCharCode() の alias $fnAscii を合成します。これで任意の文字を獲得可能になりました。
$h = $fn($return+" '\\"+$x+$6+$8+"'")(); // new Function("return '\x68'")() -> "h" $C = $fn($return+" '\\"+$x+$4+$3+"'")(); // new Function("return '\x43'")() -> "C" $fromCharCode = $S+$t+$r+$i+$n+$g+"."+$f+$r+$o+$m+$C+$h+$a+$r+$C+$o+$d+$e; // "String.fromCharCode" $fnAscii = $fn($n,$return+" "+$fromCharCode+"("+$n+")");
-
console.log("Hello World") を実行するために不足している "H" と Console Object への参照を獲得し、実行します。
$ConsoleObject = $WindowObject[$c+$o+$n+$s+$o+$l+$e]; $fnConsoleLog = $ConsoleObject[$l+$o+$g]; $H = $fnAscii($7*$10+$2) $fnConsoleLog($H+$e+$l+$l+$o+" "+$W+$o+$r+$l+$d); // console.log("Hello World");
上記のコードを結合するとこうなります。
$0 = +[]; // 0 (-[] or +"") でも可能
$1 = -~[]; // 1
$2 = $1+$1; // 2 (1+1)
$3 = $2+$1; // 3 (2+1)
$4 = $3+$1; // 4 (3+1)
$5 = $4+$1; // 5 (4+1)
$6 = $3<<$1; // 6 (3<<1)
$7 = $6+$1; // 7 (6+1)
$8 = $2<<$2; // 8 (2<<2)
$9 = $3*$3; // 9 (3*3)
$10 = $5<<$1; // 10 (5<<1)
$Object = ""+{}; // "[object Object]"
$false = ""+![]; // "false"
$true = ""+!![]; // "true"
$undefined = ""+[][[]]; // "undefined"
$c = $Object[$5];
$n = $undefined[$1];
$o = $Object[$1];
$r = $true[$1];
$s = $false[$3]
$t = $true[$0];
$u = $undefined[$0];
$constructor = $c + $o + $n + $s + $t + $r + $u + $c + $t + $o + $r;
$Array = ""+([][$constructor]); // "function Array() { [native code] }"
$String = ""+(""[$constructor]); // "function String() { [native code] }"
$RegExp = ""+(/ /[$constructor]); // "function RegExp() { [native code] }"
$Number = ""+($0)[$constructor]; // "function Number() { [native code] }"
$Infinity = ""+($1/$0); // "Infinity"
$NaN = ""+(+{}); // "NaN"
$a = $false[$1];
$b = $Object[$2];
$d = $undefined[$2];
$e = $true[$3];
$f = $false[$0];
$g = $RegExp[$10+$1];
$i = $Infinity[$3];
$j = $Object[$3];
$l = $false[$2];
$m = $Number[$10+$1];
$p = $RegExp[$10+$4];
$v = $RegExp[$10+$10+$5]
$x = $RegExp[$10+$3]
$y = $Infinity[$7];
$A = $Array[$9];
$E = $RegExp[$10+$2];
$I = $Infinity[$0];
$N = $Number[$0];
$O = $Object[$8];
$R = $RegExp[$9];
$S = $String[$9];
$return = $r + $e + $t + $u + $r + $n;
$self = $s + $e + $l + $f;
$FunctionObject = ""[$constructor][$constructor] // function Function() { [native code] } -> new Function()
$fn = $FunctionObject;
$WindowObject = $fn(($return+" "+$self))(); // new Function("return self")() -> [Object Window]
$Window = ""+$WindowObject; // "[object Window]"
$W = $Window[$8];
$w = $Window[$10+$3];
$h = $fn($return+" '\\"+$x+$6+$8+"'")(); // new Function("return '\x68'")() -> "h"
$C = $fn($return+" '\\"+$x+$4+$3+"'")(); // new Function("return '\x43'")() -> "C"
$fromCharCode = $S+$t+$r+$i+$n+$g+"."+$f+$r+$o+$m+$C+$h+$a+$r+$C+$o+$d+$e; // "String.fromCharCode"
$fnAscii = $fn($n,$return+" "+$fromCharCode+"("+$n+")");
$ConsoleObject = $WindowObject[$c+$o+$n+$s+$o+$l+$e];
$fnConsoleLog = $ConsoleObject[$l+$o+$g];
$H = $fnAscii($7*$10+$2)
$fnConsoleLog($H+$e+$l+$l+$o+" "+$W+$o+$r+$l+$d); // console.log("Hello World");
お疲れ様でした。