Original thread: http://www.reddit.com/r/IAmA/comments/hj4a4/iama_guy_who_is_taking_3_days_off_of_work_to/

To date, I have gathered up about 40 GHz worth of computing horsepower working around the clock in an attempt to brute-force crack Z340Q3 (Zodiac 340, Quadrant 3). Grand total, i've generated about 14 billion keys so far, and perhaps predictably so, I have not yeilded anything solid.. A few provocative misses, but nothing above instances of 3 four-letter words.. something which could be chalked up to "monkeys at typewriters generating Shakespeare" sort of stuff.

(For the curious, read below. A few days ago, one match came back with "wait bus bomb", which seemed tantalizing since the Zodiac killer referred repeatedly to blowing up schoolbuses full of kids... However, the match proved to be just a randomly generated fluke.)

Anyway, I had a novel idea while working on the latest incarnation of code.. Why not give it away on Reddit, and see what happens?

So, here it is:

wget http://ltbcomputers.com/zodiac/zodiac.txt <--rename to .pl

wget http://perlmonks.org/?abspart=1;displaytype=displaycode;node_id=910936;part=1


wget http://leetupload.com/code/zodiac.pl

wget http://c590198.r98.cf2.rackcdn.com/zodiac.txt <-- rename to .pl

wget http://jeanniepearson.com/z340crack.pl

I'm hoping that someone out there will see a hit, which will be displayed both on screen as well as dumped to a file in /tmp called zodiac.txt. For those who are able, have a look at the code, and make whatever modifications you like. I figure with a massive parallelization of effort, it might increase our odds a wee bit. The potential keyspace of the problem is absolutely enormous from what i'm told, something like (1.9x1028)/4 if we concentrate on a single quadrant, so, don't expect any miracles. Although, a miracle is precisely what we're looking for. :)

...Happy cracking!

UPDATE: Best Result To Date (6/29/11):

MATCH FOUND: hlcjbjfbbyjksclptplfrekzjkfjytsswgjtctoschkhjuocspillibjbtbbvrbcrhbloodfcbknifes (Count: 4, blood spill knife tosch ), pass 2161751
a equals () b equals (HO;T) c equals (Z39H&) d equals (C) e equals (7) f equals (5KO) g equals (>K) h equals (#_Y) i equals (:I) j equals (VLM1) k equals (]8) l equals (BW) m equals (]B) n equals (A) o equals (G}-M) p equals (KFV) q equals (F) r equals (I6{O) s equals (X3) t equals (4SUC=7) u equals (%-X) v equals (;A:') w equals (}8E) x equals (T) y equals (2G5) z equals (WR)

Comments: 1876 • Responses: 20  • Date: 

[deleted]397 karma

After approximately 3 minutes of attempting to crack the code, I have reached a definite conclusion. I am extremely underqualified to decode anything and I have no business meddling about in this post.

bpoag102 karma

...If you hit Ctrl-C, you will forever have to live with the fact that the very next key could have been the one, which would have landed you fame and fortune and many women. :)

Laughingstok335 karma

Hey guys, I responded to the author but no response yet. I got a hit. But a little background. I edited the script to include the zodiacAlphabet into the regular alphabet and also added slices of the original encryption (5 characters long each) as words to look for as hits.

I received the following hit.. please help me understand.. did I just find 3 instances of 3 slices of its own "encryption?"

Processing: Pass #1136403 [ha>MznYtzynSczaGHGaxGMSUMSxYy>ccHeYYMHHc>OSGnMSicGXGaxT9t1qzYGT>zhtaUHhxMtSoxYMc]

MATCH FOUND: yBulhSE7hkSeX3BF4FBVq7FsleVnk4XXxLn}C4dXubebSIeTXFfVBLxa73:hKqxuSy7BiduVC7FfLE7X (Count: 3, X3BF4 3BF4F BF4FB ), cycle 1136408

    a equals (L)    b equals (#_)   c equals ()     d equals (-)    e equals (]G)
    f equals (:A)   g equals ()     h equals (T)    i equals (})
    j equals ()     k equals (2)    l equals (1)    m equals ()
    n equals (V)    o equals ()     p equals ()     q equals (6)
    r equals ()     s equals (R)    t equals ()     u equals (C9)
    v equals ()     w equals ()     x equals (;E)   y equals (Y)
    z equals ()     = equals ()     > equals (I)    _ equals ()
    - equals ()     ; equals ()     : equals (H)    ' equals ()
    ] equals ()     { equals ()     } equals (U)    & equals ()
    # equals ()     % equals ()     1 equals ()     2 equals ()
    3 equals (S3)   4 equals (4=)   5 equals ()     6 equals ()
    7 equals (7O)   8 equals (F)    9 equals ()     A equals ()
    B equals (B)    C equals (Z)    E equals (K)    F equals (8)
    G equals ()     H equals ()     I equals (%)    K equals (')
    L equals (>)    M equals ()     O equals ()     R equals ()
    S equals (M{)   T equals (&)    U equals ()     V equals (W5)
    W equals ()     X equals (X)    Y equals ()     Z equals ()

[deleted]61 karma

You know you aren't finding anything right? The "processing pass" text is just printing out every 9th cipher text. This means nothing, look at the cipher text in the MATCH FOUND text box only as it is the one that actually matches.

Here is the original string


and the matched strings (from your two matched passes) yBulhSE7hkSeX3BF4FBVq7FsleVnk4XXxLn}C4dXubebSIeTXFfVBLxa73:hKqxuSy7BiduVC7FfLE7X


The parts that are matching are unchanged from the original cipher text. Meaning they havent been deciphered at all from the original, so no, they are not "double encrypted". Since you added pieces of the original text to the match dictionary, it is expected that undeciphered portions of the cipher would match.

Also this means either OP's code is buggy or your edits to his code are buggy.

[deleted]80 karma

It looks like the bug is here:


The replacement symbols are actually cycling. In your first matching pass, OP's code first replaces all F's in the cipher with 8 and then replaces all 8's in the cipher back to F. X, 3, B, and 4 all map to themselves. This is why the deciphered string looks like it is unchanged for those letters.

This is a crippling bug in the software. Don't waste your time running it.

*EDIT OP pointed out that his original code uses different symbols for each alphabet so the bug is not in the original version, it was introduced by Laughingstok.

TL;DR programming on a team sucks

bpoag14 karma

My original code doesn't do multiple replacements of a given symbol--it's only happening because Laughingstok added the zodiac alphabet to the normal alphabet. The two need to be unique to avoid the transposition bug you're referring to.

tl;dr - His modifications bork my code, not the other way around. :)

baddaddvice283 karma

I'm familiar with the story and the letters, but I'm confused about what your code is doing, exactly. What is Z340Q3? What are you brute-forcing? If someone gets a hit, what is that hit, exactly? Sorry for being dumb, I'm interested but clueless.

bpoag233 karma

Z340Q3 is a block of ciphertext located in Quadrant 3 of the Z340 letter. The quadrants are laid out according to folds made in the paper sent to police. See here:


I chose this quadrant based on it being smaller than the others, and therefore (perhaps) easier to crack from a statistical standpoint. The fewer bytes, the better. 54, in this case.

The code makes a few assumptions about what the decrypted message contains. It assumes that at least one of about 30 or 40 "signal words" will be present. I call them signal words because they presumably represent signal versus noise -- They're long enough, and unusual enough that it would be improbable to hit upon them randomly. The code will announce a match if at least 3 of these signal words are present.

The signal words themselves are a combination of commonly-used words the Zodiac killer used in his other letters, and mispelled words he used.

I decided to focus on words that were at least 5 characters long, since four-letter words were occuring randomly fairly often.. I was getting about 20 matches per day. Admittedly, some of them were interesting, but they could all ultimately be chalked up to chance and confirmation bias on my part.

"wait bus bomb" was one of them. I took my time on that one, since the Zodiac had repeatedly referred to blowing up school buses full of kids.

nojustice33 karma

Isn't it easy enough to verify if a given hit is the right decoding or not? Say you get a hit that says "wait bus bomb". Can't you just take whatever encoding produced that hit and decode the entire message with it? A brief look at the result will tell you whether its garbage with a few real words here and there or a clear, well-formed message.

bpoag84 karma


However, "wait bus bomb", if it were a legitimate partial match, would have only been correct for letters W, A, I, T, B, U, S, O, and M. The rest of the key would be incorrect.

I imagine that soon i'll try to write something genetic.. I want my code to see something like the "wait bus bomb" and say, "Oh, hang onto those letters and keep going.. Lets assume for the next billion keys that W, A, I, T, B, U, S, O and M are correct.

For fun, here's what my desktop looks like, where I monitor what's going on:


As you can see......empty boxes so far. :(

lemmings279 karma

Z340Q3 is im sure a specific section of the Zodiac killer's encoded message. His code as attempting to brute force attack this message in an effort to decode it. A brute force attack is similar to running through the dictionary to find passwords, you just try every single possibility starting at 1 and ending at infinity.

A hit is when the message POSSIBLY seems to have been decoded. For instance if there was a three letter encoded section FGH and one of your brute force attacks returned THE it is possible that whatever deciphering technique was running at that time could decode the rest. It also may have just been a coincidence.

Im not too familiar with the actual zodiac killer's encrpytions, but thats the best layman's terms I got.

bpoag27 karma

You are correct.

hobbykitjr19 karma

Trying every combination of sequences or replacements and looking to see if any real words come out.

A = 1, b = 2... nothing? a = 2, b = 3, ... nothing? etc.

Something like that, like he said, brute force.

bpoag52 karma


Think of a car's odometer, except instead of 6 digits wide showing 0 thru 9, it's 54 digits wide, showing A thru whatever weird symbol.

Now, start driving, and watch the odometer:




In our car, it's:



eirthepriest38 karma


bpoag18 karma


Its all random. By the time the keyspace was exhausted via random trial and error, it would be ages.

Sanit259 karma

I managed to decipher the code into a URL which brought me to an image file on the web. It seems to be an image of baron landscape. Maybe a desert or something. Could be where he buries his victims. I'll run some image processing algorithms to see if I can get some more info/data out of the photo and then give you guys an update.

Sanit575 karma

Update: Just looking at the image again and its balls. A close up photo of balls. Never mind.

bpoag99 karma

lol. :)

Watch, we'll crack it, and it'll be the lyrics to the Monkee's "Daydream Believer" or something equally useless.

FredWampy122 karma

Nice try, SETI.

bpoag42 karma


NoMoreNicksLeft102 karma

Dude, he wasn't a cryptographer. It's probably some stupid book code or whatever.

mellonandenter209 karma

Or complete gibberish.

bpoag85 karma

It's certainly possible. It depends on which school of thought you're in -- The school that says this guy was a publicity hound, or the school of thought that says he enjoyed dicking with the police. He was both.

bpoag49 karma

There is some indication that he may have studied up on crypto before sending Z340 to the cops. Some of the weird symbols used on the Halloween Card match symbols found in recently published books on crypto at that time.

irishwhite92 karma

And the Zodiac claims another victim...

bpoag76 karma

Fuck that shit, i'm still fighting! :)

phthano84 karma

Are you trying GPU cracking, and if not, why not?

bpoag39 karma

I don't know a thing about CUDA. :(

insomniaclyric58 karma

I thought they figured this out already. I remember reading about how someone discovered that if you fold the message a certain way you get a really direct reference to the site of one of the killings. I'll see if I can find the link.

Found it: http://www.opordanalytical.com/articles1/zodiac-340.htm

edit: link

bpoag43 karma

Tea leaves. It's far from a "solution".

It's like saying Mickey Mouse killed them because the killer was seen dressed in a costume in California.

controversy18749 karma

I followed your progress in your previous post, and I have one concern for your approach. They way I understand how you are going about this is that each quadrant is encoded independently of the others, but also that it was originally written independently of the others. It seems more likely to me that the message was written line-by-line, divided into quadrants and then encoded on a quadrant basis. If that is the case, an individual quadrant won't contain only whole-words, as words will inevitably cross quadrant boundaries, resulting in non-words in the quadrant. Assuming all that is true, it seems that attacking the largest quadrant first would result in a larger dataset and therefore more opportunities for whole words. Just throwing out another idea. It seems like your code is easily modifiable to drop in the quadrants, so maybe some people might to try running it on the other quadrants.

bpoag19 karma

That is a possibility. Again, not knowing the size of the fish, I can't select the right lure. I have to go on the assumption the lure is attractive enough, and small enough to have a fish eat it.

The code can be easilly modified to attack other quadrants. Just change $cipherText to whatever encoding method you want, and make sure the $zodiacAlphabet reflects the symbols in the ciphertext itself.

drucey42 karma

I don't know a single thing about the contents of that link- but explain it in simple retard terms, and I'll run the thing 24/7

bpoag28 karma

It's a computer program written in a language called Perl.

For the geeks among us, they will copy and paste the contents of that link into a file, and then use Perl to execute it. Doing so will cause their computers to generate a metric f*#kload of possible solutions to the cryptogram.

The program will alert the user of a match is found.

heartbraden30 karma

And for the non-programmers that still would like to help, what's the best way to go about helping? I have a couple of high-end gaming rigs here right now that I'd like to dedicate while not in use :)

edit: Got it running! :)

bpoag14 karma

Download and install Perl, then use Perl to run this script.

bonestamp20 karma

One question. Why didn't you take our advice from the original thread and build something that you could execute against the cloud with much more cpu power? I even offered to chip in some money to help cover the costs. Maybe your existing code could be used in the cloud, but it doesn't sound like you considered it. I'm not being critical, but since you've spent time on this maybe you found a good reason not to use the cloud.

bpoag33 karma

Thought about it, actually. No offense, but, I didn't want to make too big a deal out of it.

I could write a distributed client and completely mechanize the effort, but, I'm not really willing to invest the time required to do so. That's a fairly large undertaking, not just the code, but providing the report-back infrastructure to make it happen... And if we're going down that road, i'd rather people spend their CPU time on cancer research, not attempting to crack what may be nothing but jibberish in the end.

MeganFoxx20 karma

Wouldn't a CIA type organization have tried brute forcing this with their own supercomputers without any leads? I always thought the postcard/letter was on to something.

bpoag37 karma

I have no idea. I'm going on the assumption that "The CIA tried to crack it with their resources" being early 70's resources... What we have today is an unholy amount more powerful.