

JSFuck – esoteric JavaScript - BenjaminRH
http://www.jsfuck.com

======
thomasfoster96
For those wondering how you get numbers, strings and other primitives from a
whole bunch of empty arrays and objects in JavaScript, here's what happens
when you do arithmetic and other operations on arrays and objects:

> [] + []

"" (An empty string)

> {} + []

0 (The number zero)

> [] + {}

"[object Object]" (.toString() called on a plain object).

> ![]

false (!{} is the same)

> !![]

true (not false)

> +[]

0 (the number zero)

> -[]

-0 (negative zero)

> +{}

NaN (Not a number, same goes for -{})

> "" \+ []

"" (empty string)

> "" \- []

0 (number zero, _not_ empty string)

And the one that gets more people than the previous list:

> typeof [] === typeof {}

true

Incidentally, some of these things can be useful. For example, +(x) will
always evaluate to a double (unless it is preceded by a string), while (x|0)
will always evaluate to a 32bit integer. asm.js abuses (to an extent) this to
have more control over types, and most JavaScript engines would now store the
result of (x|0) as an integer internally instead of a double.

~~~
jaseemabid
Does knowing any of this make you a better programmer? I'd say no.

Should you be using any of this in production code? No

The next programmer even if he is a really good one might not know that
particular esoteric trick.

I'm not trying to vote down or anything, but what is the point? Most of it
look like language design warts to me. Most of them should have thrown
exceptions and errored out.

Now I'm loving the idea of static typing a lot more.

~~~
xanderjanz
Useful for obfuscating executable JS for security reasons.

~~~
BinaryIdiot
Security through obscurity is not security. This would be easy to translate
back into the original code anyway. This is also not efficient from a file
size perspective which is cancer on the web.

------
frik
It was on HN 2 years ago with some interesting comments: "JSFuck – Write any
JavaScript with 6 Characters: []()!+":
[https://news.ycombinator.com/item?id=6379732](https://news.ycombinator.com/item?id=6379732)

One interesting question was about the "performance impact"? One reply was:
"Vanilla I got 225k ops/sec. JSFuck, 4.5 ops/sec. So about 50000 times
slower."

------
devsquid
Wow, its amazing that you developed this. A healthy mixture of too much free
time and being clever.

------
userbinator
Great abuse of the implicit type conversion system.

Amazing that a simple alert("Hello world!") expands to over 16KB.

~~~
anon4
Yes, but if you gzip it, you should get a much smaller file.

~~~
dorgo
A good test for compression algorithms.

------
BinaryIdiot
For shits and giggles I tried to use the minified version of my open source
library. After about 30 minutes of Chrome being frozen I gave up, lol. I was
curious how large it would balloon 17kb of JavaScript.

------
lol768
I seem to remember CloudFlare using this approach (for obfuscation purposes)
when users enable the 'under attack' mode on their sites. I was pretty
surprised something like this was possible when I first saw the code.

------
kenrick95
with eval checked,

    
    
       alert(1)

will produce 1227 chars while

    
    
       alert(1);

will produce 9535 chars. Interesting.

~~~
Tloewald
Well ; produces 8307 chars on its own (without eval checked) -- which seems
kind of inefficient (for such a common character in idiomatic javascript).
Looking that their encoder, ';' actually has a specific encoding (which itself
has to be encoded) so it looks like there's some inefficient expansion taking
place (e.g. '.' has a specified encoding that does not require recursive
encoding). Encoding the string "link" in the expansion of ';' appears to be
very expensive -- alert is cheap in comparison because you can obtain its
letters from Javascript return values (e.g. "l" is pulled out of "false" which
is obtained by (![]+"")[2])

I'd imagine that if you were serious about this, you'd implement, say,
e=String.fromCharCode (12k chars) and use that to dig yourself out of a lot of
this expensive stuff if you need more than one hard-to-encode character.

------
_random_
Just like vanilla JS: [http://wtfjs.com](http://wtfjs.com)

~~~
pluma
That's the joke. It's a strict subset of JS, not a transpiled language.

------
yyhhsj0521
hah. I tried to, eh, encrypt the source code of JSFuck itself at
[https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuc...](https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js)

------
haddr
Amazing! I wonder if it's difficult to "disassemble" the JSFuck code?

~~~
rsuelzer
This article is pretty good on piecing it stuff like this together:
[https://blog.korelogic.com/blog/2015/01/12/javascript_deobfu...](https://blog.korelogic.com/blog/2015/01/12/javascript_deobfuscation)

------
homakov
Not useful for obfuscation :( Just remove last ()

------
dxcqcv
so js is a cipher code.

------
soheil
I know this will most likely come as a surprise to most Javascript programmers
but all code is represented using only two "characters" deep inside your
little computers!

~~~
leppr
What do you mean two characters? What are they exactly? I'm guessing $ and ;
because it's like jQuery but some operations seem impossible, like how does it
even assign variables?

~~~
Xophmeister
I think he meant 1 and 0

~~~
soheil
yes

