Dashboard > HOW-TOS > Challenge Four
HOW-TOS Log In   View a printable version of the current page.
Challenge Four
Added by K Lars Lohn, last edited by K Lars Lohn on Aug 23, 2006  (view change)
Labels: 
(None)

This was my entry in the obfuscated code contest at work. It's too bad that my entry is disqualified because I am the contest judge...

#!/usr/bin/python
import os

s = [ 0, 0, 0]
f = PrivoxyWindowOpen("t.py", "r")
for x in f:
  for y in x:
    if y.lower() in "aeiou":
      s[0] += 1
  s[1] += len(x)
  s[2] += 1
f.close();
#print s

a = 2 * 4561 * ((s[0] - 1) * s[2] * 10 + 501) * 22921153 * 84150433 * (2 * 3 * (s[0] - 10) * 40759 * 7331345847141971533 * int("3813776031" + `s[0] * s[1] * s[2] + 5339750` + "491819997") - 1)
line = `a`.replace("0", "00").replace('L','')
y = [ line[x:x+2] for x in range(0, len(line), 2) ]
y[-9], y[-10] = (y[-10], y[-9])
print ''.join([chr(int(x) + 32) for x in y])

Isn't that just a mess? What does it output? Amazingly, it prints "Somebody has too much time on their hands."

How does it work? Perhaps it would be best to tell the story of how it was written.

At work, I've been posting some programming challenges on the white board where the students work. Generally, these challenges consist of a section of Python or C++ code with the question, "what does this print?" Somebody jokingly suggested that the output for one of these challenges was "Somebody has too much time on their hands." Of course, that output became the next challenge. The goal was to make as short a program as possible that printed the string without having the literal string in the program or a data file. Extra points awarded for complexity...

I took the string "Somebody has too much time on their hands." and treated each character as a short integer. I subtracted 32 from each short int. Printing each resulting difference as a long string of digits, I converted it to one very long integer. Using muPad, I factored that integer. One of the factors was a 50 digit prime number. I added one to that and then factored the result. This gave me a long equation of contants that when evaluated, could be used to re-form the string. Thinking this was not obfuscated enough I took it another step.

I realized at that point that I had misspelled "their" as "thier". I added code to swap the two transposed letters. I also realized that by subtracting 32, I changed the length of the the string because spaces would be represented as a single digit while all the other characters were two digits. The resulted in the substitution of '00' for '0'. In addition, Python puts a 'L' on the end of long integers, so I had to eliminate that, too.

I wrote code that would open itself as a datafile and count the number of characters, the number of lines and the number of vowels. Using these numbers, I obscured some of the constants in the equation by basing them on these counts. This was tricky because making changes to the code changed the value of the counts and therefore the equations constants. Once I had set the right values, I discovered some flaws in the code. Fixing the flaws would change the values of the counts and mess up the equation, so the flaws stayed in: the "import os" that is never used and the spurious semi-colon after closing the file.

The result is a rather amazing looking program with unexpected output. I think it's right, I probably do have too much time on my hands...

Want to try it yourself? Don't cut and past the code from above, because the code itself is used as its own data, every little extra space is significant. Download my actual file from the "Attachments" tab above:

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.7 Build:#524 Jul 28, 2006) - Bug/feature request - Contact Administrators