The Alert to Life, the Universe and Everything, Part 2 – “Don’t Lose my Number”

So my previous post had this gorgeous monstrosity:

[][(__=”+!!(_=+[]))[_$=-~-~-~_]+($$=”+{})[$=-~_]+($_=”+!_)[$]+$_[_]][$$[-~($+_$)]+$$[$]+(”+$/_)[$]+__[_$]+$_[_]+$_[$]+$_[$+$]+$$[-~($+_$)]+$_[_]+$$[$]+$_[$]](__[$]+__[$+$]+$_[_$]+$_[$]+$_[_]+”(“+((($<<($<<$)^$)<<($<<$)^$)<<$)+”)”)()

This code results in an alert with the number 42 in it…

So, how do we get from that code to 42? Well, as I said in my previous post, a lot of it deals with loose typing and some pretty cool math wizardry. I’m going to focus on the numerical side of things in this post so that we can see how we’re getting numbers when there are no numbers in sight.

Before I begin, I also mentioned in my previous post that some awesome variable naming conventions were being used. Take a look at the following instances that are present in the code:

  • _ (single underscore)
  • __ (double underscore)
  • $ (single dollar)
  • $$ (double dollar)
  • $_ (dollar underscore)
  • _$ (underscore dollar)

JavaScript accepts all these as valid variable names. If I were to restrict my definition to the ASCII subset of what’s valid, a valid JavaScript variable name can consist of any combination of numbers, lowercase and uppercase Latin letters, underscore and dollar sign, provided it doesn’t start with a number. The best full definition for valid JavaScript variable names can be found here.

So, because we have variable names in the code, the equal signs next to them are used for assignment.

So, now that we’ve established that, let’s focus on the numbers.

Firstly, we have the following snippet:

_=+[]

What’s the go with this, I hear you ask? Here, we’re assigning the value of _ to 0. To explain this, we need to establish what we already know about falsy values. Falsy values are what can be coerced to false when acted on by a Boolean operator. To determine whether a value or object is falsy, you apply the logical double-not operator on it and view the result. If the result is false then your original value is falsy. 0 is a falsy value, an empty string “” is falsy, and so is an empty array []. Applying the unary positive operator + on a falsy value coerces it to zero.

So _=+[] is identical to _=0.

You may have noticed this variable assignment its nested within another variable assignment:

(__=”+!!(_=+[]))

This is valid JavaScript. Granted, it’s not pretty, but it’s valid nonetheless. The purpose of doing this is so that the variable can be used at the time the variable is being defined. In this instance, __ is defined as an empty string concatenated to the double-not Boolean of 0. If you’ve read previous posts of my blog, you’d know that the double-not operator coerces the 0 to false, the Boolean value, and the empty string with the concatenation operator coerced that, in turn, to “false”, the string. But we’ll focus on the string parts in my next post.

The next variable assignment of interest is the following:

_$=-~-~-~_

Minus tilde, minus tilde, minus tilde… So it’s repeated three times, but what does that mean? Let’s look at the following:

-~0

We knew the underscore variable in our example was zero, so I’ve rendered it out as such. The tilde operator takes the number to the right of it, and performs the following algorithm on it -(N+1), then spurs back the result. In this example, ~0 is equal to -(0+1) = -1. Seems like a strange thing for an operator to do, but it works. So we have -1, but we also have the additional unary negative operator in front of it, do this coerces to -(-1) or 1. So technically -~N is the same as N+1.

So, that would mean that _$=-~-~-~_ is the same as _$=0+1+1+1 which means we’ve just written the equivalent of _$=3. Similarly, the $=-~_ reference in ($$=”+{})[$=-~_] is equivalent to $=1.

Next, we have the encapsulated statement in $$[-~($+_$)]. $+_$ based from the previous paragraphs is equivalent to 1 ($) plus 3 (_$) which is 4, but with the -~ operators, this raises it to 5. So this statement is the same as $[5].

Following this section there’s third little nugget…

$/_ … But if you do your substitutions that works out to be 1/0, which is mathematically infinite… Well, luckily, JavaScript has the Infinity value… We’ll address how Infinity comes into play in this code in the next post…

And the $+$ reference is simply 1+1 which is equal to 2.

Lastly, we have this “centrepiece” statement:

((($<<($<<$)^$)<<($<<$)^$)<<$)

This makes use of the number 1 (the value of $) over and over again… But why?

Here’s why, let’s substitute $ for one and see what we have.

(((1<<(1<<1)^1)<<(1<<1)^1)<<1)

Two operators here at work, the left-bitwise shift operator (<<) and the bitwise XOR operator (^).

Quick lesson on how these two work:

The bitwise left shift operator (we’ll call it the BLSO from here on) takes the number and shifts all bits one bit to the left. With each shift, you’re essentially doubling the number. The general formula is that X<<Y is equivalent to doubling X, Y times. So 5<<1 = 10, 5<<2 = 20 and so on. Bear in mind this works specifically for the integers party of your numbers only. If you executed 9.6<<1 your answer will be 18 not 19.2.

1<<1 is therefore 2 so let’s substitute it back in:

(((1<<2^1)<<2^1)<<1)

Note the section in bold: (1<<2^1), the BLSO takes precedence over the XOR operator, so we run it through again:

(((4^1)<<2^1)<<1)

So the XOR operator, what happens here? The XOR operator in this case compares the numbers bit by bit, and returns true if and only if the bit in both numbers are not identical, otherwise. 1 and 0? Return 1. 0 and 1? Return 1. 1 and 1 or 0 and 0? Return 0. So in our first case, 4^1, i.e. 4 XOR 1 I’d worked out as:

4: 100

1: 001

XOR: 101 = 5

This is a rather clever way of adding 1 to any multiple of 2 as any multiple of 2 will naturally have that 1’s bit (the one at the very right of a positive binary number) set to zero. So, 1<<1^1 is 3, 2<<3^1 is 17 and so on.

So let’s plug it and chug it over and over, using what we’ve learned and see what we get.

(((4^1)<<2^1)<<1)4^1 = 5

((5<<2^1)<<1) …5<<2 is 5×2×2 = 20

((20^1)<<1) …20^1 = 21

21<<1 …21<<1 = 42

We have our magical 42 popping up… So what’s the go with the rest of the code? This, my dear readers, is the code for the JavaScript alert, but we will get to that within the next few posts. Before I go, let’s take another look at that original code:

[][(__=”+!!(_=+[]))[_$=-~-~-~_]+($$=”+{})[$=-~_]+($_=”+!_)[$]+$_[_]][$$[-~($+_$)]+$$[$]+(”+$/_)[$]+__[_$]+$_[_]+$_[$]+$_[$+$]+$$[-~($+_$)]+$_[_]+$$[$]+$_[$]](__[$]+__[$+$]+$_[_$]+$_[$]+$_[_]+”(“+((($<<($<<$)^$)<<($<<$)^$)<<$)+”)”)()

Now let’s take a look at that same code with all the numbers rendered out:

[][(__=”+!!(_=0))[_$=3]+($$=”+{})[$=1]+($_=”+!_)[1]+$_[0]][$$[5]+$$[1]+(”+Infinity)[1]+__[3]+$_[0]+$_[1]+$_[2]+$$[5]+$_[0]+$$[1]+$_[1]](__[1]+__[2]+$_[3]+$_[1]+$_[0]+”(“+42+”)”)()

A little more recognizable… But you’ve noticed we have a lot of array references here, yet no arrays have been created?

Well, they have, but not how you’d expect… I’ll tell you more in the next post, also entitled “I’ve got no strings on me”. Stay tuned!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s