Alphanumerics are for sissies!

August 19th, 2010 by FireFly

JavaScript is an interesting language. In a conversation in ##javascript on FreeNode, khamer showed me an example of one of the oddities it has:

<khamer> jseval (!![]+[][[]]+[])[+[]]+([]+[][[]])[+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+!+[]+!+[]+!+[]]
<buubot> khamer: Nice

Naturally, I evaluated certain extracts of it, and the way it works is that strings like “undefined” are generated (e.g. by [][+[]]+[]; the concatenation with an empty array implicitly casts it to String), and then indexed to fetch individual letters.

The alphabet “()[]!+” was used in the line by khamer, and by adding “/” one can also get “Infinity”. With this, I could spell out “firefly”. By adding in the object literal “{}”, one can also get the letters in “[object Object]“. The “c” in “Nice” isn’t generated through {}, though, but instead by indexing an array with “filter”, then fetching the c in “function filter() { [native code] }”.

My reply, after a while, was this “firefly” code:

(![]+[])[+[]]+([][![]]+[])[+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+!![]]+(!![]+[])[+[]+!+[]+!+[]+!+[]]+(![]+[])[+[]]+(![]+[])[+[]+!+[]+!+[]]

I just realized one don’t even need the parentheses; (foo) == [foo][0] == [foo][+[]]. This means the minimum alphabet is “[]!+”. With the alphabet “[]!+/{}”, one can get these characters: ” ()INO[]abcdefijlnorstuvy{}/!+”.

The same “firefly” string, without parentheses:

[![]+[]][+[]][+[]]+[[][+[]]+[]][+[]][+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+[]][+[]][+[]+!+[]]+[!+[]+[]][+[]][+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][+[]]+[![]+[]][+[]][+[]+!+[]+!+[]]+[!+[]/+[]+[]][+[]][+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]

Now I wonder, is it possible to reduce the input alphabet even further, or to generate an even wider range of characters as output?

Edit:

1
2
N: [[+[]+[[][+[]]][+[]]]+[]][+[]][+[]]
u: [[][+[]]+[]][+[]][+[]]