An online friend of mine has tried to make a virtual cat game several times and gave up each time.  But this time is different.  This time, she has the support of a programmer, and I won’t let her give up.

Sir Soybean... VKitty?

The new VKitty is all ajaxified, so there is only one full pageload for each time you visit your virtual cat, and everything else is handled by XMLHttpRequests.  Being admin on VKitty does have its advantages, as I am allowed to do things nobody else can do—adopt a llama and have over nine million cat cash, for example.

There are currently five different adoptable cat types.  None of them require any food or play yet, because VKitty is not quite done.  But at a rate of one update or more per day, it’s getting closer and closer to being finished.

Already, stats refresh twice a minute directly from the server, dates update twice a second using the JSON-encoded responses the server gives, there’s a fully searchable memberlist, and much more.

Unfortunately, each adoption costs five thousand cat cash, and when you join VKitty, you are only supplied with 250.  If anyone needs help adopting, until the “free kitten for joining” offer is in place, I’ll be glad to help.  Just send me an email at nigh@vkitty.co.cc

If you have any suggestions for VKitty, you can suggest them here, and view the development here.

Without further ado, please join VKitty!

Unpacking /packer/

Ever since I started working on the mostly Ajax app “VKitty“, I’ve been looking into JavaScript compression, and trying to figure out how it works.  Most compressors have very simple ways to compress JavaScript, by simply removing whitespace, but Dean Edwards’s /packer/ defies the simplicity of most compressors by making an unreadable function that acts the same as the JavaScript you feed it, also known as obfusication.

I’ve decided to find out how it works, and I’m starting with something very simple.  “alert(‘STUFF GOES HERE’)“.

First, I packed it in /packer/.  I got back the code “eval(function(p,a,c,k,e,r){e=String;if(!”.replace(/^/,String)){while(c–)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return’\\w+’};c=1};while(c–)if(k[c])p=p.replace(new RegExp(‘\\b’+e(c)+’\\b’,’g’),k[c]);return p}(‘0(\’1 2 3\’)’,4,4,’alert|STUFF|GOES|HERE’.split(‘|’),0,{}))“, which is really unreadable.

Let’s unpack the /packer/.

I did a bit of formatting on the function returned by /packer/: (it’s an image because I couldn’t get syntax highlighting to work on my blog)

/packer/: Unpacked

/packer/: Unpacked (Click for a bigger view)

If you can’t already see what’s happening, I’ll walk you through it.  It basically creates a function, calls itself, and evaluates the result as JavaScript.  Here it is, line by line:

Line 1: eval(
Evaluates the code that is created by the function.

Line 2: function (p, a, c, k, e, r) {
Starts the declaration of a function, via shameless plug.

Line 3: e=String;
Makes the variable e into a function that returns whatever it is given as a string.

Line 4: if (!”.replace(/^/, String)) {
This seems pointless to me, because evaluating the code inside the if statement would always return true.  I even removed the code, and it kept working!  The code is probably for compliance with less-up-to-date JavaScript implementations.

Line 5: while(c–) r[c] = k[c] || c;
While the c variable is above zero, reducing c by 1 every time, the r variable (an empty object) gets a new variable inside it: one of the words contained in k, or ‘alert|STUFF|GOES|HERE’, split at the |‘s.  If the variable doesn’t exist (which shouldn’t happen), it puts the key into the array so it will replace with itself.

Line 6: k = [function (e) {
The variable k is turned into an array with a function inside it.

Line 7: return r[e]
Return the xth word in r. (x is the variable e)

Line 8: }];
Closing the function-in-an-array statement.

Line 9: e = function () {
The variable e is now another function, not the String function, let’s see what it does:

Line 10: return ‘\\w+’
In regex, this means “find as many alphanumeric characters as possible”.

Line 11: };
Closing a function.

Line 12: c=1
We are no  longer looking for words 4 (in this case) times, but 1.  This is only possible because of the stuff inside the if statement.

Line 13: };
Ending an if statement.  Note the unnecessary semicolon.

Line 14: while (c–)
While the variable c is nonzero, reducing it by 1 after we test for nonzero-ness.

Line 15: if (k[c])
Make sure k has c as one of its keys.

Line 16: p = p.replace(new RegExp(‘\\b’+e(c)+’\\b’,’g’), k[c]);
Replace the p variable with the k[c] variable instead of the c variable’s value.

Line 17: return p
Return the final value.

Line 18: } (‘0(\’1 2 3\’)’, 4, 4, ‘alert|STUFF|GOES|HERE’.split(‘|’), 0, {})
Set the p, a, c, k, e, r variables.

Line 19: )
Close the eval statement.