Edited at

JavaScript で記号プログラミング

More than 1 year has passed since last update.


JavaScript で記号プログラミング

JavaScript も他の言語と同様に記号($=_-+~[]{}()*/<!\;"',.)のみを使ったプログラミングが可能です。

以下に console.log("Hello World") を実行するための手順を説明します。


コードに出てくる $0$a などの変数は、読者への説明のために可読性のある形で記述しています。

もちろん、これらの変数は記号のみを使った形に書き下すことが可能です。




  1. まずは記号から数値を導出します。

        $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)



  2. 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];



  3. 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;



  4. Window Object への参照を獲得します。

        $WindowObject   = $fn(($return+" "+$self))();       // new Function("return self")() -> [Object Window]
    
    $Window = ""+$WindowObject; // "[object Window]"
    $W = $Window[$8];
    $w = $Window[$10+$3];



  5. 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+")");



  6. 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");

お疲れ様でした。