LoginSignup
8
4

More than 5 years have passed since last update.

【JavaScript】10種類の文字とwindow,文字列'CogS'だけでHelloWorld(前編)

Last updated at Posted at 2018-02-27

以前の投稿で、windowオブジェクトと'SCgohm'という文字列があれば
(_,)=>!-[]などのいくつかの文字だけを使ってJavaScriptを難読化できそうみたいな話をしたんですが、
よく考えると文字列は'CogS'だけで済みそうと気づいたので
とりあえずHelloWorldを難読化してみます。
使う文字は少し変わって(_,)=>!+[]です。

目標は次の関数と同じ仕事をするものです。

HelloWorld.js
function helloWorld(){
    console.log('Hello, World!');
}

実行するとコンソールにHello, World!と表示するプログラムですね。

1.下準備

まずはじめに、やんごとなき理由から、関数の定義を関数式に置き直します。

HelloWorld1-0.js
const helloWorld = function(){
    console.log('Hello, World!');
};

続いて、この関数式を返す関数を即時実行して代入するスタイルに変更します。

HelloWorld1-1.js
const helloWorld = (function(){
    return function(){
        console.log('Hello, World!');
    };
})();

なんでこんなことをしたかというと、
'(_,)=>!-[]'という文字だけで記述する部分を限定するためです。
この即時間数の中だけ'(_,)=>!-[]'という文字のみで記述するのを目的とします。

1.1. window'CogS'の準備

window'CogS'を使うたびにこれらの文字を記述していては意味がないので、
_という文字だけを使ってこれらにアクセスできるように、

HelloWorld1-2.js
const helloWorld = (function(_,__){
    return function(){
        console.log('Hello, World!');
    }
})(window,'CogS');

てな感じで即時関数の引数に入れてしまいましょう。
これで即時関数の中でwindow'CogS'を自由に使えるようになりました。
ただ、このままではあまりにも分かりにくくなるので、
一旦は原型を止めた変数名に変えておきましょう。

HelloWorld1-3.js
const helloWorld = (function(w,cogs){
    return function(){
        console.log('Hello, World!');
    }
})(window,'CogS');

1.2. 変数置き場の準備

HelloWorldくらいなら変数を置いておく場所がなくても書けるんですが、
同じ記述が何度も出てきてしまうので、
変数入れる場所として配列を用意してあげましょう。

HelloWorld1-4.js
const helloWorld = (function(w,cogs){
    v = [];
    return function(){
        console.log('Hello, World!');
    }
})(window,'CogS');

もちろんこのvという文字は、あとで___などに置き直します。

constletvarと書けないので宣言なしで書いてしまいましたが、
このままだとグローバル的な変数のvに配列が入ってしまいます。

このスクリプトより後に読み込まれたスクリプトで、
undefinedがほしくてwindow.vにアクセスする人がいたら困りますし、
これより前に読み込まれたスクリプトの先頭に
無情にも'use strict'と書かれていればそもそも動かなくなります。

なのでこいつは、即時関数の引数とみなしてあげましょう。

HelloWorld1-5.js
const helloWorld = (function(w,cogs,v){
    v = [];
    return function(){
        console.log('Hello, World!');
    }
})(window,'CogS');

これで他人の心配をしなくて済むようになりました。

2. 関数名の文字列化

まずは関数名やオブジェクト名を直接書かなくていいように文字列にしましょう。
consoleオブジェクトは実はwindow.consoleオブジェクトで、
windowオブジェクトのプロパティとしてアクセスできます。
そして、プロパティには.でつなげる以外にも、window['console']という書き方があります。
console.logについても同様にconsole['log']として、こいつらを組み合わせると、

HelloWorld2-1.js
const helloWorld = (function(w,cogs,v){
    v = [];
    return function(){
        w['console']['log']('Hello, World!');
    }
})(window,'CogS');

という風になり、consolelogと直接記述せずにconsole.logを呼べるようになりました。
あとは'console','log','Hello, World!'という文字列を用意してやるだけです。

イメージとしては

HelloWorld2-1.js
const helloWorld = (function(w,cogs,v){
    v = [
        'console',
        'log',
        'Hello, World!'
    ];
    return function(){
        w[v[0]][v[1]](v[2]);
    }
})(window,'CogS');

こんな感じですね。

3. 文字の準備

3.1. String.fromCharCodeがほしい

さて、文字列を使わずに文字列を定義するのはどうすればいいでしょうか。
パッと思いつきそうなのは、String.fromCharCodeです。
こいつがいれば、数字さえ用意できればJavaScriptで扱えるどんな文字でも手に入れられるはずです。
数字の入手方法はあとで考えるとして、まずはString.fromCharCodeを呼ぶ方法を考えましょう。

まずは、先程と同じように、オブジェクトや関数を文字列に置き直すと、

String.fromCharCode-0
String.fromCharCode

と書くべきところを

String.fromCharCode-1
w['String']['fromCharCode']

と書けば済むようになります。
ではこの文字列をどうやって用意すればいいでしょうか。
とりあえずここでcogsに入っている'CogS'を利用してみましょう。

String.fromCharCode-2
w[cogs[3]+'trin'+cogs[2]]['fr'+cogs[1]+'m'+cogs[0]+'har'+cogs[0]+cogs[1]+'de']

なんのこっちゃわからないかもしれませんが、
単に'String','fromCharCode'の中にある'C','o','g','S'を、
それぞれcogs[0],cogs[1],cogs[2],cogs[3]で置き換えただけです。

難読化としてはこのままでもそれなりな気がしますが、
目的は難読化ではないので残っている文字が問題です。
小文字't','r','i','n','g','f','m','h','a','d','e',が足りません。
実はこれらの一部は後述する方法で手に入るのですが、
それでも'g','m','h'は(僕の知る限り)手に入れられません。
別の方法を考える必要があります。

3.2. 小文字がほしい

こうなってくるとどんな小文字でも返してくれる関数がほしくなります。
そんな都合のいい関数があるでしょうか。

あります。

この事実に気づいてなかったので、以前の投稿では'SCgohm'という文字が欲しかったのです。
例えば'console'という文字列がほしかったら、次のように書きましょう。

'console'-0
27612545666..toString(36)

知ってる人でないと意味が分からないかもしれません。

亜種として、次の2文を見てください。

`abadface`
0xABADFACE.toString(16)
2880305870..toString(16)

これらはどちらも'abadface'という文字列を返します。
1文目は簡単ですね。16進数でABADFACEとなる数字を16進数で書いたものです。
2文目の2880305870という10進数の数字は、16進数でABADFACEとなるので同じ結果が帰ってくるというわけです。
こっそり悪口を仕込みたい場合に、1文目のように書くとすぐバレますが、
2文目のように書けばすぐにはバレないでしょう1

原理はこれと同じです。
よく使われるr進数は2進数、8進数、10進数、16進数くらいのものですが、
JavaScriptでは2進数から36進数まで使えます。
アラビア数字は10個しかシンボルがないので、
残った26個のシンボルとしてアルファベットの小文字が使われます。
16進数と同じように、a10を、b11を、というのを、
そのまま続けてzまで行くと、これは35を表しています。

最初の記述に戻って、

'console'-0
27612545666..toString(36)

ですが、これは36進数でconsoleと表される数27612545666を36進表記で書いたものなので、
'console'という文字列が返ってくるのでした。

ちなみに、'console'には28を表現するシンボルであるsより後の文字が含まれていないので、

'console'-1
7647118590..toString(29)

と書いても'console'が返ってきます。
この辺は好みで使い分けてください。
Number.MAX_SAFE_INTEGERを超えなければ大丈夫でしょう。

3.3. toStringがほしい

それではString.fromCharCodeを記述するために、
まずは'tring'という文字列を用意しましょう。
次のように書けば'tring'が返ってきます。

'tring'-0
49992748..toString(36)

そういえば使える文字は'(_,)=>!-[]'だけだったので、ピリオドを使わずに、

'tring'-2
(49992748)['toString'](36)

と書き直します。

ここで使われている'toString'という文字列を作るには、
cogsを使っても、't','r','i','n'が足りません。
これを用意する方法を考えてみましょう。

3.3.1. 't'がほしい

tで始まる単語で、JavaScriptを使っているとたまに使うことになるかもしれないものがあります。
それはtrueです。
true.toString()とすれば、文字列'true'が手に入るので、その0番目の要素を取り出せば't'という文字が作れます。

toStringのためにtoStringを使うと堂々巡りになってしまうため、
実際には別の方法でtrueを文字列にします。

JavaScriptには、数字でないものを足そうとすると、
文字列の結合とみなして勝手にtoStringしてくれたりする機能があります。
例えば、

'true'-0
'' + true

とすれば、'true'が返ってきます。
この機能は別に文字列で始める必要があるわけではないようで、

'true'-1
[] + true

としても、[].toString()true.toString()を結合して'true'を返してくれます2

ここで、trueをどうやって用意するかですが、
みんな大好き!+[]を使えば手に入ります。
+[]0と評価され、それをブール値とみなして論理反転してtrueが返ってくるという仕組みです。

これらをまとめると、次のようにすれば文字't'が手に入ります。

't'
([]+!+[])[+[]]

3.3.2. 'r','i','n'がほしい

ここまでくればあとはやり方は同じです。
'r''true'に含まれているので、

'r'
([]+!+[])[+!+[]]

として1番目の要素をとってくれば済みます。

'i','n'ですが、これらはundefinedに含まれているので、

'i'-0
([]+[][+[]])[5]
'n'
([]+[][+[]])[+!+[]]

とすることで手に入ります。

ここで、'i'の方には5という少し大きな数字があります。
!+[]+!+[]+!+[]+!+[]+!+[]としてもいいのですが、次のように書くと少しスマートです。

'i'-1
([![]]+[][+[]])[[+!+[]]+(+[])]

これは何をしているのかというと、
'false''undefined'を結合して'falseundefined'という文字列を作り、
その10番目の要素である'i'にアクセスするのに
'1''0'を結合してできた'10'という文字列を使っています。

分解すると次のような感じです。

'i'-2
(
     [![]]      // [false]
    +[][+[]]    // + undefined
)[              // falseにundefinedを直接足すとNaNになるので注意
     [+!+[]]    // [1]
    +(+[])      // + 0
]               // 当たり前ですがこっちも直接足すと1になります

// 最終的に('false'+'undefined')['1'+'0'] -> 'falseundefined'['10']

3.3.3. みんなの希望toString

これでtoStringを記述するのに必要なパーツが揃いました。
早速書き下してみましょう。

'toString'-0
([]+!+[])[+[]]+cogs[+!+[]]+cogs[!+[]+!+[]+!+[]]+([]+!+[])[+[]]+([]+!+[])[+!+[]]+([![]]+[][+[]])[[+!+[]]+(+[])]+([]+[][+[]])[+!+[]]+cogs[!+[]+!+[]]
'toString'-1
 ([]+!+[])[+[]]                 //t
+cogs[+!+[]]                    //o
+cogs[!+[]+!+[]+!+[]]           //S
+([]+!+[])[+[]]                 //t
+([]+!+[])[+!+[]]               //r
+([![]]+[][+[]])[[+!+[]]+(+[])] //i
+([]+[][+[]])[+!+[]]            //n
+cogs[!+[]+!+[]]                //g

下のはわかりやすく改行しただけです。

さて、このtoStringですが何度もお世話になることになるので毎回書いていられません。
変数置き場に置いておきましょう。

HelloWorld3-1.js
const helloWorld = (function(w,cogs,v){
    v = [
        ([]+!+[])[+[]]+cogs[+!+[]]+cogs[!+[]+!+[]+!+[]]+([]+!+[])[+[]]+
                ([]+!+[])[+!+[]]+([![]]+[][+[]])[[+!+[]]+(+[])]+([]+[][
                +[]])[+!+[]]+cogs[!+[]+!+[]]
    ];
    return function(){
        w['console']['log']('Hello, World!');
    }
})(window,'CogS');

'toString'を変数置き場の配列の0番目の要素に入れています。
あとあまりにも長いので適当に改行しています。
改行位置は意味のあるまとまり等ではありません。

これで今度から'toString'がほしい時はv[+[]]として
vの0番目の要素にアクセスするだけで済みます。

3.4. 満を辞してString.fromCharCode

toStringがいれば小文字なんか怖くないので、
さっさとString.fromCharCodeも用意してしまいましょう。

'String'-0
 cogs[3]                    //'S'
+(49992748)['toString'](36) //'tring'
'fromCharCode'-0
 (735718)['toString'](36)   //'from'
+cogs[0]                    //'C'
+(22419)['toString'](36)    //'har'
+cogs[0]                    //'C'
+(31586)['toString'](36)    //'ode'

さて、ここで大きな整数がたくさん出てきています。
例えば36は、次のようにすれば得られます。

36
+(                                      //文字列'36'を数字として評価する
     [!+[]+!+[]+!+[]]                   //'3'
    +[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]    //+'6'
)

これをすべての数字でいちいち手書きしてたら気が遠くなるので、
整数を(+![])だけを使った表現に置き換える関数を用意しておきましょう。

ConvertNum.js
const convertNum = n=>'+('+n.toString().replace(/\d/g,d=>{
    if(d==='0'){
        return "[+[]]+"
    }
    let str = d==='1'?'[+':'[';
    str += [...Array(parseInt(d,10))].map(e=>'!+[]').reduce((a,b)=>a+'+'+b);
    str += ']+';
    return str;
}).replace(/\+$/,')');

この関数の解説は割愛しますが、これでいちいち手書きで整数を置き換えなくて済みます。
数字ごとに変換するなり、
ソースを読み込んで.replace(/\b\d+\b/g,convertNum)するなりしましょう。

'String''fromCharCode'は、それぞれ次のようになります。

'String'-1
/* S */      cogs[!+[]+!+[]+!+[]]
/* tring */ +(+([!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))['toString'](+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))
'fromCharCode'-1
/* from */  (+([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))['toString'](+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))
/* C */    +cogs[+[]]
/* har */  +(+([!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))['toString'](+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))
/* C */    +cogs[+[]]
/* ode */  +(+([!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))['toString'](+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))

馬鹿馬鹿しいのでもう改行はしていません。
これでやっとString.fromCharCodeを次のように呼べるようになりました。
この中の'toString'v[+[]]で置き換えてやると、次のように書けます。

String.fromCharCode-3
w[/* String */
    cogs[!+[]+!+[]+!+[]]+(+([!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+
            !+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+
            []+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]
            ]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+
            []+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))[v
            [+[]]](([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))
][/* fromCharCode */
    (+([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]
            +!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[
            ]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))[v[+[]]](+([!
            +[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))+cogs[+[]]+
            (+([!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[+!+[]]+[!
            +[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))[v[+[]]](+([!
            +[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))+cogs[+[]]+
            (+([!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[
            ]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+
            !+[]+!+[]]))[v[+[]]](+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[
            ]+!+[]+!+[]]))
]

こいつを変数置き場に突っ込んでおきましょう。

HelloWorld3-2.js
const helloWorld = (function(w,cogs,v){
    v = [
        ([]+!+[])[+[]]+cogs[+!+[]]+cogs[!+[]+!+[]+!+[]]+([]+!+[])[+[]]+
                ([]+!+[])[+!+[]]+([![]]+[][+[]])[[+!+[]]+(+[])]+([]+[][
                +[]])[+!+[]]+cogs[!+[]+!+[]]
    ];
    v[+!+[]] = w[cogs[!+[]+!+[]+!+[]]+(+([!+[]+!+[]+!+[]+!+[]]+[!+[]+!+
            []+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]
            +!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!
            +[]+!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!
            +[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!
            +[]+!+[]]))[v[+[]]](([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+
            !+[]+!+[]]))][(+([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]
            +!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]
            +!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[
            ]+!+[]]))[v[+[]]](+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!
            +[]+!+[]]))+cogs[+[]]+(+([!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]
            +!+[]+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[
            ]+!+[]]))[v[+[]]](+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!
            +[]+!+[]]))+cogs[+[]]+(+([!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[
            ]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]
            +[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))[v[+[]]](+([!+[]+!+[]+!+[
            ]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))];
    return function(){
        w['console']['log']('Hello, World!');
    }
})(window,'CogS');

これで、String.fromCharCodeを呼びたくなったらv[+!+[]]とだけ書けばよくなりました。

3.5. 禁断の秘術eval

String.fromCharCodeを手に入れたので、
どんな文字でも書けるようになりました。
どんな文字でも書けるということは、つまり

"()=>console.log('Hello, World!')"

という文字列も書けるわけです。
もちろん、

'eval'

なんて文字列はお茶の子さいさいです。

さて、ここで

w['eval']("()=>console.log('Hello, World!')")

は何が返ってくるでしょうか。

実行するとコンソールにHello, World!と表示するプログラムですね。
目的は達成されました。
次のようにすれば"()=>console.log('Hello, World!')"が得られます。

HelloWorldFunctionString
[+([!+[]+!+[]+!+[]+!+[]]+[+[]]),+([!+[]+!+[]+!+[]+!+[]]+[+!+[]]),+([!+[
]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]),+([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+
[!+[]+!+[]]),+([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[
]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]),+([+!+[]]+[+!+[]]+[+!+[]]),+([+!
+[]]+[+!+[]]+[+[]]),+([+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]),+([+!
+[]]+[+!+[]]+[+!+[]]),+([+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+
[]+!+[]]),+([+!+[]]+[+[]]+[+!+[]]),+([!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!
+[]+!+[]+!+[]+!+[]]),+([+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[
]+!+[]]),+([+!+[]]+[+!+[]]+[+!+[]]),+([+!+[]]+[+[]]+[!+[]+!+[]+!+[]]),+
([!+[]+!+[]+!+[]+!+[]]+[+[]]),+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!
+[]+!+[]+!+[]+!+[]+!+[]]),+([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+
!+[]]),+([+!+[]]+[+[]]+[+!+[]]),+([+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+
[]+!+[]+!+[]+!+[]]),+([+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]
+!+[]]),+([+!+[]]+[+!+[]]+[+!+[]]),+([!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!
+[]+!+[]]),+([!+[]+!+[]+!+[]]+[!+[]+!+[]]),+([!+[]+!+[]+!+[]+!+[]+!+[]+
!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]),+([+!+[]]+[+!+[]]
+[+!+[]]),+([+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]),+([+!+[]]+[+[]]+[!+[
]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]),+([+!+[]]+[+[]]+[+[]]),+([!+[]+!
+[]+!+[]]+[!+[]+!+[]+!+[]]),+([!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[
]+!+[]+!+[]+!+[]+!+[]]),+([!+[]+!+[]+!+[]+!+[]]+[+!+[]])]
/* map */[+(([!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[
]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+
[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+)[v[+!+[]]]([!+[]+!+
[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+)]
(_=>v[+!+[]](_))
/* join */[+(([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]+[!
+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]]+[!
+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+)[v[+!+[]]]([!+[]+!+[]+!+[
]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+)]
([]+[])

何をしているかというと、
"()=>console.log('Hello, World!')"のそれぞれの文字コードが入った配列を用意して、
それぞれString.fromCharCodeで文字に変換してjoinでつなげているだけです。

ちなみに、'eval'は、

'eval'
 ([]+!+[])[!+[]+!+[]+!+[]]
+v[+!+[]](+([+!+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]))
+([]+![])[+!+[]]
+([]+![])[!+[]+!+[]]

です。
めでたしめでたし。

で終わってもいいんですが、
いろいろと問題があるのでそういうわけにもいきません。

が、長くなってきたせいか、変なコード書いたせいか、
プレビュー画面がおかしくなってきているので、
今日のとこはこのくらいにしておきます。

続きはそのうち書きます。
書きました(2018-10-29 追記)。


  1. こんなことはしないようにしましょう。 

  2. 多分正しくありません。 

8
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4