JavaScript(ECMAScript6)、1行あたり2バイト
'\
'[
'\
b\
i\
g'
][
'\
c\
o\
n\
s\
t\
r\
u\
c\
t\
o\
r'
][
'\
c\
a\
l\
l'
](
0,
`\
n\
=\
p\
r\
o\
m\
p\
t\
(\
'\
'\
)\
;\
i\
=\
0\
;\
f\
o\
r\
(\
;\
+\
+\
i\
<\
=\
n\
;\
c\
o\
n\
s\
o\
l\
e\
.\
l\
o\
g\
(\
i\
%\
5\
?\
f\
|\
|\
i\
:\
f\
+\
'\
P\
i\
e\
'\
)\
)\
f\
=\
i\
%\
3\
?\
'\
'\
:\
'\
A\
p\
p\
l\
e\
'\
`)
()
長い説明
行を短くする方法は、コードを文字列に変換し、行の終わりをエスケープすることです。これにより、行ごとに2バイトの制限が課されます。
そうalert(1)
なる
"\
a\
l\
e\
r\
(\
1\
)"
しかし、今あなたのコードは文字列なので、文字列をコードとして実行する必要があります。文字列をコードとして実行できる少なくとも4つの方法を知っています。
- eval(code)。呼び出しには少なくとも5バイトかかります
eval(
- setTimeout(code、timeout)。関数を非同期に実行しますが、オプションで文字列を渡すと、内部でevalが呼び出されます。
- DOMを利用してコードを
onclick=""
属性内に配置することはできますが、要素作成部分を短くすることはできませんでした。
- Functionコンストラクターnew Function()を呼び出すと、コードを解析して、後で呼び出すことができる匿名関数にします(これを使用しました)。
内部のすべてのネイティブ関数の命ウィンドウオブジェクトとJavaScriptであなたが使用してオブジェクトのプロパティにアクセスすることができ、ドット表記そうeval()
になりwindow.eval()
、または使用してプロパティにアクセスすることができブラケット表記を window['eval']()
。これをeval
利用して、前述の方法を使用して複数行に分割できます。ただし、ウィンドウを入力する必要があります。1つの秘isは、フレーム内にいない場合、があります。1つの秘isは top変数もwindowなので、window.evalがtop.eval(3バイト少ない)になることです。
w=top
w['eval']
You can shorten the assignment using parenthesis
w=(
top
)
w[
'e\
av\
al'
](
/*string*/
)
したがって、これによりコードは最小で3バイトになります。コードを2バイトにするには、new Function(/*string*/);
コンストラクターを使用しましたが、入力せずにアクセスするには創造的でなければなりませんでした。
まず、Functionコンストラクターを使用すると、新しいキーワードを省略した関数として呼び出すことができます。これにより4バイトが削減されますが、別の理由でも重要です。コンストラクターを関数として呼び出すと、インスタンスが返されます。これによりnew Function(code)
、Function(code)
。もう1つの重要なことは、Functionコンストラクターにはcall
、this参照をオーバーライドするが、任意の関数を呼び出すことができるメソッドがあり、Functionコンストラクター自体は、自分自身のようにメソッドを呼び出すことができる関数であるということですFunction.call(null, code)
。
すべてのネイティブ関数はFunctionコンストラクターのインスタンスであり、javascriptのすべてのオブジェクトにはコンストラクタープロパティがあります。そのためalert.constructor
、などのネイティブ関数のFunctionコンストラクターにアクセスでき、callメソッドを使用して、コンストラクターを関数として実行できます。これで、alert.constructor.call(null、code)が関数を返します。
以前のテーマを組み合わせて、それを alert['constructor']['call'](null, code)
ここで、短い名前の関数またはメソッドを見つける必要があるため、Stringコンストラクター内でbig()メソッドを選択します。空の文字列から直接アクセスできます"".big
"".big.constructor.call(null, "code")();
''['big']['constructor']['call'](0,'/* code */')()
それから私はちょうど2バイトですべてのものを壊しました
ショートERの説明(TLDR)
新しいFunction(code)コンストラクターにアクセスして、eval(code)の代わりに文字列を解析しています。このコンストラクターは、anyFunctionを実行することにより、すべてのネイティブ関数で使用できます。のようなコンストラクタalert.constructor===Function
。私はString.prototype.big 内で関数/メソッドを使用していますString.prototype.big.constructor.call(null, /*string*/)
が、文字列リテラルから直接アクセス"".big
し、ブラケット表記に変えました 。""['big']['constructor']['call'](0, CODE)
を使用してそれを破ることができ\
ます。