Few months ago I saw an email asking if someone could unwrap this one line of JavaScript.

```
<pre id=p><script>n=setInterval("for(n+=7,i=k,P='p.\\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P",k=64)</script>
```

This line will render just like the image below. You can see it in your browser here. It was created by Mathieu ‘p01’ Henri, author of www.p01.org where you can find this and many other cool demos.

Challenge accepted!

Reverse Engineering One Line of JavaScript

#javascript https://t.co/a1JheNcJSq— Alex Kras (@akras14) July 13, 2017

## Part 1. Making the code readable

First things first, I kept HTML in the HTML and moved JavaScript into a `code.js`

file. I also wrapped p in the `id="p"`

in quotes.

*index.html*

```
<script src="code.js"></script>
<pre id="p"></pre>
```

I noticed that there was a variable `k`

, which was just a constant, so I moved it out of the line, and renamed it as `delay`

.

*code.js*

```
var delay = 64;
var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var n = setInterval(draw, delay);
```

Next, the `var draw`

was just a string, that was being executed as `eval`

within setInterval, since setInterval can accept a function or a string to be evaluated. I moved it to an actual function. I kept the old line there, though, for reference.

Another thing that I noticed was that element `p`

was actually referring to the DOM element with id `p`

that was declared in HTML, the one I recently wrapped in quotes. Turns out elements can be referenced by their id name from JavaScript, as long as the id name is made up of alpha-numeric characters only. I added the `document.getElementById("p")`

to make it more intuitive.

```
var delay = 64;
var p = document.getElementById("p"); // < --------------
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
for (n += 7, i = delay, P = 'p.\n'; i -= 1 / delay; P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2]) {
j = delay / i; p.innerHTML = P;
}
};
var n = setInterval(draw, delay);
```

Next, I declare the variables `i`

, `p`

, and `j`

, and moved them to the top of the function.

```
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
var i = delay; // < ---------------
var P ='p.\n';
var j;
for (n += 7; i > 0 ;P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2]) {
j = delay / i; p.innerHTML = P;
i -= 1 / delay;
}
};
var n = setInterval(draw, delay);
```

I factored out `for`

loop into a `while`

loop. Keeping only the CHECK_EVERY_LOOP part of `for`

‘s 3 parts: (RUNS_ONCE_ON_INIT; CHECK_EVERY_LOOP; DO_EVERY_LOOP), and moving everything else in or outside of the body of the loop.

```
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
var i = delay;
var P ='p.\n';
var j;
n += 7;
while (i > 0) { // <----------------------
//Update HTML
p.innerHTML = P;
j = delay / i;
i -= 1 / delay;
P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2];
}
};
var n = setInterval(draw, delay);
```

I unroll ternary operator ( `condition ? do if true : do if false`

) in `P += P[i % 2 ? (i % 2 * j - j + n / delay ^ j) & 1 : 2];`

.

`i%2`

was checking if `i`

was even or odd. If i was even, it was just returning 2. If i was odd, it was returning the magic value of `(i % 2 * j - j + n / delay ^ j) & 1;`

(more on that in a bit).

Finally that index was used to offset into string P, so it became `P += P[index];`

.

```
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
var i = delay;
var P ='p.\n';
var j;
n += 7;
while (i > 0) {
//Update HTML
p.innerHTML = P;
j = delay / i;
i -= 1 / delay;
let index;
let iIsOdd = (i % 2 != 0); // <---------------
if (iIsOdd) { // <---------------
index = (i % 2 * j - j + n / delay ^ j) & 1;
} else {
index = 2;
}
P += P[index];
}
};
var n = setInterval(draw, delay);
```

I factored out `& 1;`

in `index = (i % 2 * j - j + n / delay ^ j) & 1`

into another if statement.

This one is a clever way of checking if the result in parentheses is odd or even, and returning 0 for even and 1 for odd. `&`

is a bitwise AND operator. Logic for AND is as follows:

- 1 & 1 = 1
- 0 & 1 = 0

Hence `something & 1`

will convert “something” to a binary representation, it will also pad 1 with as many 0 in the front as needed, to match the length of something, and will return just an AND of the last bit. For example, 5 in binary is `101`

, if we AND it with `1`

will get the following:

```
101
AND 001
001
```

In other words, 5 is odd, and result of 5 & 1 is 1. It’s easy to confirm that this logic holds in a JavaScript console.

```
0 & 1 // 0 - even return 0
1 & 1 // 1 - odd return 1
2 & 1 // 0 - even return 0
3 & 1 // 1 - odd return 1
4 & 1 // 0 - even return 0
5 & 1 // 1 - odd return 1
```

Note that I also renamed rest of `index`

to `magic`

, so the code with unrolled `&1`

will looks as follows.

```
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
var i = delay;
var P ='p.\n';
var j;
n += 7;
while (i > 0) {
//Update HTML
p.innerHTML = P;
j = delay / i;
i -= 1 / delay;
let index;
let iIsOdd = (i % 2 != 0);
if (iIsOdd) {
let magic = (i % 2 * j - j + n / delay ^ j);
let magicIsOdd = (magic % 2 != 0); // &1 < --------------------------
if (magicIsOdd) { // &1 <--------------------------
index = 1;
} else {
index = 0;
}
} else {
index = 2;
}
P += P[index];
}
};
var n = setInterval(draw, delay);
```

Next I unrolled `P += P[index];`

into a switch statement. By now it’s clear that index can only be one of three values – 0, 1, or 2. It’s also clear that P always gets initialized with the following values – `var P ='p.\n';`

. Where 0 points to `p`

, 1 points to `.`

and 2 points to `\n`

– a new line character.

```
var delay = 64;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
var draw = function() {
var i = delay;
var P ='p.\n';
var j;
n += 7;
while (i > 0) {
//Update HTML
p.innerHTML = P;
j = delay / i;
i -= 1 / delay;
let index;
let iIsOdd = (i % 2 != 0);
if (iIsOdd) {
let magic = (i % 2 * j - j + n / delay ^ j);
let magicIsOdd = (magic % 2 != 0); // &1
if (magicIsOdd) { // &1
index = 1;
} else {
index = 0;
}
} else {
index = 2;
}
switch (index) { // P += P[index]; <-----------------------
case 0:
P += "p"; // aka P[0]
break;
case 1:
P += "."; // aka P[1]
break;
case 2:
P += "\n"; // aka P[2]
}
}
};
var n = setInterval(draw, delay);
```

I cleaned up the `var n = setInterval(draw, delay);`

magic. Set interval returns an integer starting with 1, and increments it by one every time `setInterval`

is called. That integer can be used to `clearInterval`

(cancel it). In our case, setInterval was being called just one time, and n was simply getting set to 1.

I also rename `delay`

to `DELAY`

to remind that it was just a constant.

Last but not least, I put parentheses in `i % 2 * j - j + n / DELAY ^ j`

to point out that `^`

bitwise XOR has lower precedence then `%`

, `*`

, `-`

, `+`

, and `/`

operators. In other words all of the computations above will be conducted first, before `^`

is evaluated. Resulting in `(i % 2 * j - j + n / DELAY) ^ j)`

.

**Update:** It was pointed out to me, that I mistakenly placed `p.innerHTML = P; //Update HTML`

inside the while loop, so I moved it out.

```
const DELAY = 64; // approximately 15 frames per second 15 frames per second * 64 seconds = 960 frames
var n = 1;
var p = document.getElementById("p");
// var draw = "for(n+=7,i=delay,P='p.\\n';i-=1/delay;P+=P[i%2?(i%2*j-j+n/delay^j)&1:2])j=delay/i;p.innerHTML=P";
/**
* Draws a picture
* 128 chars by 32 chars = total 4096 chars
*/
var draw = function() {
var i = DELAY; // 64
var P ='p.\n'; // First line, reference for chars to use
var j;
n += 7;
while (i > 0) {
j = DELAY / i;
i -= 1 / DELAY;
let index;
let iIsOdd = (i % 2 != 0);
if (iIsOdd) {
let magic = ((i % 2 * j - j + n / DELAY) ^ j); // < ------------------
let magicIsOdd = (magic % 2 != 0); // &1
if (magicIsOdd) { // &1
index = 1;
} else {
index = 0;
}
} else {
index = 2;
}
switch (index) { // P += P[index];
case 0:
P += "p"; // aka P[0]
break;
case 1:
P += "."; // aka P[1]
break;
case 2:
P += "\n"; // aka P[2]
}
}
//Update HTML
p.innerHTML = P;
};
setInterval(draw, 64);
```

You can see the final result in action here.

## Part 2. Understanding what the code does

So what is going on here? Let’s see.

Initial value of `i`

is set to 64 via `var i = DELAY;`

, and it’s decremented by 1/64 (0.015625) on every loop via `i -= 1 / DELAY;`

. The loop goes on until `i`

is no longer greater than 0 `while (i > 0) {`

. Every run of the loop, `i`

is decremented by 1/64th, so it will take 64 loops for `i`

to decrement by 1 (64/64 = 1). In total then `i`

would have to be decremented 64 x 64 = 4096 times, to become below 0.

The image consist of 32 rows, with 128 chars in every row. Conveniently 64 x 64 = 32 x 128 = 4096. `i`

will only be even (not odd `let iIsOdd = (i % 2 != 0);`

) when `i`

is strictly an even number. We’ll get it to happen 32 times, when i is 64, 62, 60 etc. These 32 times, the index will be set to 2 `index = 2;`

and a new line character will be added to the line `P += "\n"; // aka P[2]`

. The rest 127 character per row will either be set to `p`

or `.`

.

But when do we set `p`

and when do we set `.`

?

Well, for starters we know that we will set it to `.`

when magic `let magic = ((i % 2 * j - j + n / DELAY) ^ j);`

is odd, and we’ll set it to `p`

when magic is even.

```
var P ='p.\n';
...
if (magicIsOdd) { // &1
index = 1; // second char in P - .
} else {
index = 0; // first char in P - p
}
```

But when is magic odd and when is it even? That’s a million dollar question. Before we talk about that though, let’s establish one more thing.

If we remove `+ n/DELAY`

from `let magic = ((i % 2 * j - j + n / DELAY) ^ j);`

, we’ll end up with the following static layout, that will not be moving at all.

For now let’s look at the `magic`

with `+ n/DELAY`

removed. How do we end up with the pretty picture above?

`(i % 2 * j - j) ^ j`

Note that for every loop we have:

```
j = DELAY / i;
i -= 1 / DELAY;
```

In other words we can express `j`

in terms of the final `i`

as `j = DELAY/ (i + 1/DELAY)`

but since 1/DELAY is such a small number, for illustration purposed we can drop `+ 1/DELAY`

and simplify it to `j = DELAY/i = 64/i`

.

Given that we can rewrite `(i % 2 * j - j) ^ j`

as `(i % 2 * 64/i - 64/i) ^ 64/i`

.

Let’s use an online graphing calculator to plot some of these functions.

First of all, let’s plot `i%2`

.

This results in a nice graph, with value of y ranging form 0 to 2.

If we plot `64/i`

will get a graph that looks like this.

If we plot the full left side, we’ll get a graph that looks kind of like combination of the 2.

Finally, if we plot 2 functions side by side we get the following.

### What do all these graphs tell us?

Let’s remind ourselves what question we are trying to answer, and that is how did we ended with a pretty static image like this:

Well, we know that if the magic `(i % 2 * j - j) ^ j`

results in an even number we’ll have to add `p`

and for an odd value number we’ll have to add `.`

.

Let’s zoom in on the first 16 rows of our chart, with `i`

values ranging from 64 to 32.

Bitwise XOR in JavaScript will drop all the values to the right of decimal point, so it’s kind of like taking a `Math.floor`

of a number.

It will return 0 when both bits are 1s or both bits are 0s.

Our `j`

will start as 1 and will slowly make its way to 2, staying right below it, so we can treat it as 1 (`Math.floor(1.9999) === 1`

), and we’ll need another 1 on the left side, to get the result to be 0 (meaning even), giving us a `p`

.

In other words, each diagonal green line represents one row in our chart. Since j is always above 1 but below 2 for the first 16 rows, the only way we can get odd value is if left side of `(i % 2 * j - j) ^ j`

aka `i % 2 * i/64 - i/64`

aka diagonal green line is also above 1 or below -1.

Here are some output from JavaScript console to drive this point home, 0 or -2 means result is even, 1 means result is odd.

```
1 ^ 1 // 0 - even p
1.1 ^ 1.1 // 0 - even p
0.9 ^ 1 // 1 - odd .
0 ^ 1 // 1 - odd .
-1 ^ 1 // -2 - even p
-1.1 ^ 1.1 // -2 - even p
```

If we look at our graph, we’ll see that the right most diagonal line barely goes above 1 or below -1 (few evens – few `p`

s), the next line goes a bit more, and the one after that even more etc. Line number 16 barely stays under 2 and above – 2. After line 16 we can see our static chart shifts a pattern.

After line 16 `j`

crosses the line of 2, and the expected result flips. Now we’ll get an even number when our green diagonal line is above 2, below -2, or within but not equal to 1 and -1. That is why we see two or more groups of `p`

s from line 17 onward.

If you look closely at the bottom few lines of the moving image, you’ll notice that they no longer follow the same pattern, due to wide fluctuation of the graph.

Let’s comeback to `+ n/DELAY`

now. In code we can see that n starts out at 8 (1 from setInteval plust 7 on every interval being called). It is then incremented by 7 every time set interval fires.

When n becomes 64, the graph changes to look as follows.

Note that `j`

is still ~1 (~ here means approximately), but now left half of red diagonal line around 62-63 is ~0 and right half around 63-64 is ~1. Since our chars get populated in decreasing order from 64 to 62, we would expect the 63-64 side of the diagonal line (1 ^ 1 = 0 // even) to append bunch of `p`

and left 62-63 side to append bunch of (1^0 = 1 // odd) `.`

, that would be growing left to right as normal English words.

Rendered HTML for that condition will look as follows ( you can hard code value for `n`

in codepen to see for yourself). Which in fact matches our expectations.

At this point number of `p`

s has grown to its constant value. For example, for the first row half of all values will always be even. From now on `p`

s and `.`

s will only shift their position.

To illustrate, when n grows by 7 on the next setInterval, the graph will change slightly.

Note that diagonal line for the first row (around 64 mark) has move roughly 1 small square up. Assuming that 4 larger square represent 128 chars, 1 large square would represent 32 chars, and 1 small square would represent 32/5 = 6.4 chars (an approximation). If we look at the rendered HTML, we’ll see that first row did in fact move right by 7 chars.

One last example. Here is what happens when setInterval gets called 7 more times with n now equal 64+9×7.

For 1st row `j`

is still equal to 1. Now the top half of red diagonal line around 64 is ~2, and the bottom one ~1. This flips the picture, since now

`1^2 = 3 // odd - .`

and `1 ^ 1 = 0 //even - p`

. So we would expect bunch of dots, followed by `p`

s.

Which renders as such.

The graph continues to loop indefinitely in a similar manner.

I hope this makes sense. I don’t think I would have ever been able to come-up with something like this on my own, but it was fun trying to understand it.

passerby says

Unfortunately, your explanation doesn’t help in understanding the magic. That’s why you don’t think you would have ever been able to do something like this.

So, just dig deeper. https://www.desmos.com/calculator/gabvherhnz will help you.

cosileone says

What graphing software did you use?

Alex Kras says

I mentioned it in the article, but it’s https://www.desmos.com/calculator

Thorsten Frommen says

Nice one, thanks a lot for all your effort!

However, there is one mistake, which seems to have only little impact on the end result.

The two lines

actually have to be switched, so we have this:

Initially, the code was a

`for`

loop with`i -= 1 / DELAY`

being the, as you described it, CHECK_EVERY_LOOP part. This means, that it will be evaluatedbeforethe body of the loop.I made a Pen that shows both versions, next to each other. You can easily adapt the

`REAL_DELAY`

constant (all the way down, just before the`setInterval()`

call) to make the animation run slower.Thanks again,

Thorsten

Tarik says

Extraordinary!

jancvanbruggen says

Thanks! Mesmerizing and informative 🙂 One tweak though, in your modified index.html the tag should go after the

<

pre> tag.

jancvanbruggen says

whoops, forgot about code formatting! 😀

in your modified index.html the

`<script>`

tag should go after the`<pre>`

tagSteven Pemberton says

Having unrolled

P += P[index];

into a switch, thus revealing the role of index, you can now merge the switch back into the if statement above:

if (iIsOdd) {

let magic = ((i % 2 * j – j + n / DELAY) ^ j); // < ——————

let magicIsOdd = (magic % 2 != 0); // &1

if (magicIsOdd) { // &1

P += “.”; // aka P[1]

} else {

P += “p”; // aka P[0]

}

} else {

P += “\n”; // aka P[2]

}

Steven Pemberton says

Sorry, it stripped my indentation when I posted.

quidditywp says

This is glorious! Thank you, both explainer and original coder!

I’d suggest tweaking this page’s max-width or the syntax-blocks’ width to ~950px in order to avoid horizontal scrollbars on screens that are big enough? (I think the main .wrap or the .crayon-syntax ?) Thanks again!

quidditywp says

Also a suggested tweak to your final output, just more detail in the left: https://codepen.io/anon/pen/MoxPaB?editors=1010

cxseven says

Yes, as iamp01 says, the ^j part makes it a checkerboard rather than just unbroken bars stretching into the horizon. You can see little spots, which become more frequent as you move downward, where the p’s and .’s pass through and get flipped. It looked like a glitch to me at first. It becomes clearer how this is working when you look at the animation without the ^j.

Devon says

Hey FYI your code blocks don’t work at all on mobile, can’t scroll horizontally at all. Android 7 in chrome.

Alex Kras says

Could you try clicking into it first please?

moeabdol says

Did you try switching it off and then on again!

iamp01 says

Hi! Thanks a ton for this write up!

It’s not every day that someone dig so deep into my code.

The part

`(i%2*j-j)^j`

is the meat of the raytracer. the`i%2*j-j`

represented the projected x, while`j`

represents the projected y. The x,y coordinates of the intersection point with the plane and the ray. Doing the`(x^y)&1`

gives the checkboard texture.It would be super sweet to point the readers to the original demo or even better to the other 64-1024 bytes Audio Visual demos at http://www.p01.org

Alex Kras says

My apologies, I purposely didn’t Google the code to avoid finding a solution, but as result I forgot to try to look for a source link. I’ll add it shortly.

Alex Kras says

Added links in the article and both CodePens. Thanks for additional explanation!

iamp01 says

Thanks again for doing such a deep write up, without cheating, and for the updates.

Cheers,

Piotr-Aueternum says

Please put innerHTML after loop its too laggy this way.

Alex Kras says

Thank you, done.

tommut says

This was a fascinating read! I didn’t realize how far down the rabbit hole it would go. 🙂

Well done.

Alex Kras says

Thank you, me neither 🙂

Alex Wilmer (@benevolentNinja) says

Fantastic writeup!

losso says

source: http://www.p01.org/128b_raytraced_checkboard/

Alex Kras says

Thank you, I specifically tried not to Google for it, to avoid clouding my “way” of trying to figure out what is going on there, but it’s nice to have a link to the original source.