Reverse Engineering Wordle

Tim Hinz
5 min readJan 26, 2022

--

It was another day at work when a co-worker of ours dropped a link to a game called Wordle. At this point I had never heard of the game, you could say I was living under a rock, but it became a regular thing at our work to start the day. Now me being the nosey developer I am, I decided to take a gander at the website source and I found a bunch of interesting things that I’d love to share with you.

In this article, we will learn about reversing a website's javascript, and then using what we learned we will create a script that will fetch the daily answer for us(for when we get stuck obviously).

Getting the games source code

Before we can write a script to fetch us the word, we need to understand how the game works internally. Thanks to the wonderful developer tools built into modern web browsers this is quite trivial.

First, we will open the developer tools in google chrome. To do this you can hit F12 on your keyboard. Once open we will have some tabs, we want the `sources` tab. At this point you should have a page that looks like this:

Now you’ll notice the code is a minified mess that is unreadable. The good news is chrome has a built-in tool to help with this as well! If you look right above the source code you will find a blue button that says “Pretty-print”. Click that button and watch the magic happen as the code becomes readable!

Finally, let’s go ahead and select all the code and copy it to our favorite code editor.

Understanding the game's code

At this point, you should have a code editor open with the game's source in it. Before we can write our solver script we need to figure out how the game's source works. The first thing you’ll notice is that while the code is formatted to be readable, the function and variable names are meaningless. This is due to the code having gone through obfuscation from what looks like webpack. This doesn’t matter too much as we don’t really care what things are called, but it’s something to be aware of.

To start let’s look over the script. There are a few approaches we can take, but the simplest, in this case, is just searching for helpful words. In our case let's search the code for the word “solution”.

After flipping through the results you will come across a really interesting code snippet where they set e.solution to the value of the function Da(e.today).

Let’s trace this down and figure out what it’s doing! Search the code for the function Da(). Once you find it you will be looking at some code like this:

function Da(e) {
var a, s = Ga(e);
return a = s % La.length,
La[a]
}

This function calls another function Ga(e) (which we will come back to in a second) as well as returns a value using the variable La. Let’s start with La to see if this is the right function. If you search for the variable La you will eventually find a variable that looks like this:

This looks like a word list to me! This tells us we’re probably in the correct function. Let’s create a new script called index.js where we will dump our findings to create our script. Go ahead and grab the variable La and paste that in your script. While you’re at it, grab the Da function and paste it as well. You should have something like this:

var La = [
"cigar",
"rebut",
// truncated for readability...
];

function Da(e) {
var a,
s = Ga(e);
return (a = s % La.length), La[a];
}

Now if you remember, the function Da also calls function Ga so we should probably figure out what that does, let’s find it!

function Ga(e) {
return Na(Ha, e)
}

This function is super simple, it takes a parameter e, then passes that to the function Na() with the variable Ha. Let’s add that to our script life then find Ha. If we search for Ha you will find a variable set to date.

var Ha = new Date(2021,5,19,0,0,0,0);

Let’s grab the whole thing and add it to our script. We should now have this:

var La = [
... // truncated for readability
];
var Ha = new Date(2021,5,19,0,0,0,0);

function Da(e) {
var a, s = Ga(e);
return a = s % La.length,
La[a]
}

function Ga(e) {
return Na(Ha, e)
}

Okay so the next piece is function Na(), let’s find it:

function Na(e, a) {
var s = new Date(e)
, t = new Date(a).setHours(0, 0, 0, 0) - s.setHours(0, 0, 0, 0);
return Math.round(t / 864e5)
}

Cool! This is the end of the road for our function chain! Just like before let’s take it and add it to our script resulting in this:

var La = [
... // truncated
];
var Ha = new Date(2021,5,19,0,0,0,0);

function Na(e, a) {
var s = new Date(e)
, t = new Date(a).setHours(0, 0, 0, 0) - s.setHours(0, 0, 0, 0);
return Math.round(t / 864e5)
}

function Da(e) {
var a, s = Ga(e);
return a = s % La.length,
La[a]
}

function Ga(e) {
return Na(Ha, e)
}

We now have all the pieces we need to finish our solver! If you remember the game source calls function Da() to start, so we should too. Let’s create a variable and store the result of the function chain:

const answer = Da(); // Note this won't work yet! Read on.

Now Da() needs a parameter called e. Let’s go back to where we started and see what it is.

e.solution = Da(e.today)

They supply e.today as the parameter, which is a variable they set, so let’s grab it.

e.today = new Date;

So using this information we can change our variable to:

const answer = Da(new Date);
console.log(answer);

All that’s left is to run it. You can run it using:

$ node index.js// Result
❯ node index.js
whack

Congrats! You have a working Wordle solver!

Conclusion

Using our code above I’ve gone ahead and created a basic webpage that will update with the answer for ease of use to show just what you can do with this code.

Thanks for reading!

Links:

--

--