JavaScript (ECMAScript6), 2 bytes por linha
'\
'[
'\
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\
'\
`)
()
Explicação longa
A maneira como podemos tornar as linhas mais curtas é transformar o código em uma string e escapar do final da linha, isso impõe um limite de 2 bytes por linha.
Então alert(1)
se torna
"\
a\
l\
e\
r\
(\
1\
)"
Mas agora seu código é uma string, então precisamos executá-la como código. Eu sei pelo menos 4 maneiras que você pode executar seqüência de caracteres como código:
- eval (código) . O que leva pelo menos 5 bytes para chamar
eval(
- setTimeout (código, tempo limite) . Executa a função de forma assíncrona, mas, opcionalmente, se você passar uma string, ela chamará eval internamente.
- Você pode tirar proveito do DOM e colocar seu código dentro de um
onclick=""
atributo, mas não consegui tornar a criação do elemento curta.
- Chamar o construtor Function new Function () analisará seu código em uma função anônima que você pode chamar mais tarde (usei isso).
Todas as funções nativas vidas dentro da janela de objeto e em javascript você pode acessar propriedades do objeto usando a notação de ponto para que eval()
se torne window.eval()
, ou você pode acessar as propriedades usando a notação de colchetes window['eval']()
. Você pode tirar vantagem disso para quebrar as eval
várias linhas usando o método descrito anteriormente. Mas você ainda precisa digitar o janela , um truque é que, se você não estiver dentro de um quadro, a variável top também será window, então window.eval se tornará top.eval (3 bytes a menos).
w=top
w['eval']
You can shorten the assignment using parenthesis
w=(
top
)
w[
'e\
av\
al'
](
/*string*/
)
Portanto, isso tornará o código mínimo de 3 bytes. Para tornar o código 2 bytes, usei onew Function(/*string*/);
construtor, mas tive que ser criativo para acessá-lo sem precisar digitá-lo.
Primeiro, o construtor Function permite chamá-lo como uma função que omite a nova palavra-chave; isso reduz 4 bytes, mas também é importante por outro motivo. Chamar o construtor como uma função ainda retorna uma instância que nos permite ativarnew Function(code)
a Function(code)
. Outra coisa importante é que o construtor Function tenha umcall
método que permite que você chame qualquer função, mas substitui a referência desta, e o próprio construtor Function é uma função que você pode chamar por si próprio.Function.call(null, code)
.
Todas as funções nativas são instâncias do construtor Function e todos os objetos em javascript possuem uma propriedade construtora . Assim, você pode ter acesso ao construtor Function em qualquer função nativa como alert.constructor
, e usando a chamada método de , podemos executar o construtor como uma função. Agora temos alert.constructor.call (null, code) retorna uma função.
combinando as técnicas anteriores, podemos transformá-lo em alert['constructor']['call'](null, code)
Agora só precisamos encontrar uma função ou método nomeado curto, então escolho o método big () dentro do construtor String. Para acessá-lo diretamente de uma string vazia"".big
"".big.constructor.call(null, "code")();
''['big']['constructor']['call'](0,'/* code */')()
Então eu apenas quebrei tudo em 2 bytes
Curto er explicação (TLDR)
Estou acessando o novo construtor Function (code) para analisar a string em vez de eval (code) . Esse construtor está disponível em todas as funções nativas executando anyFunction. construtor , como alert.constructor===Function
. Eu estou usando uma função / método dentro do String.prototype.big String.prototype.big.constructor.call(null, /*string*/)
Mas acessando-o diretamente de um literal de seqüência de caracteres "".big
e o transformou em notação de colchete . ""['big']['constructor']['call'](0, CODE)
para poder quebrá-lo usando o \
.