challenge 19

Lately, keeping busy reading about programing without actually doing any got my brain itching again. The kind of itch that is perhaps most easily scratched by the small puzzles presented in the Python Challenge.

Challenge 19 is titled ‘please!’. It presents you with a strange picture of India with the colors, well… off (inverted?). Looking in the page source you will find an email hidden in a block comment. The email is from Leopold the subject line says;

what do you mean by “open the attachment?”

the message text reads;

It is so much easier for you, youngsters.
Maybe my computer is out of order.
I have a real work to do and I must know what’s inside!

It is a multipart message with a file named “indian.wav” attached at the bottom. As is standard (I now know) the attachment is encoded in base64. Since encoding/decoding email attachments is common place I figured this part should go quickly. I installed the tmail ruby gem and quickly wrote a small script to open the email. It didn’t work. I was able to read the message and any of the tags in the email, but it always failed to open the attachment. Finally I went to the tmail website and read all the way to the bottom of of the quick start guide I find this;

. . . TMail does not touch the body of the mail message, for example, it doesn’t encode, decode, handle character sets etc.

Well that’s pretty useless!

Ok, not entirely I suppose, it gives you access to the elements within an email message and then you are expected to write your own code to actually manipulate the data.

Luckily the author of tmail wrote a new mail gem called ‘mail’ that can automatically decode attachments. It still turned out to be a lot harder than it should have. Although ‘tmail’ had no trouble with the email header ‘mail’ choked on it until I changed the content_type: from “Multipart/mixed” to “multipart/mixed”

With indian.wav successfully decoded you will find a bit of white noise interrupted by somebody saying “sorry!” sorry. html is no good (c’mon, it wouldn’t be that easy!). There is something else hidden in the wave file. Lets go to Stanford and learn a little bit more about the wav format.

Before I even read the page one word jumped out at me ‘endian’. Endian, Indian, get it. So the riddle has something to do with the endianness of the wav data. To test this theory I fired up Audacity and imported the file as raw data changing the data to big endian from the default wav standard of little endian. The resulting sound clip is of a singer calling me an idiot and laughing at me. That solves the riddle, but how to code it? Ruby has no support for audio manipulation (that I could find). However, the wav format is pretty straightforward, there is a 44 byte header followed by 4 byte audio data sub chunks. Since endianness is simply the order of data by importance (little endian is least important to most; big endian is most import to least) I should be able to simple grab each sub chunk in order and reverse them to get the decoded file.
Surprise! it worked!

#! /usr/bin/env ruby1.9
require 'rubygems'
require 'mail'

email ='please.txt') # open the email message

rd, wr = IO.pipe # use a pipe; mail attachment has Strong data type
if fork
  wav_bytes = # read data from the pipe into a string'idiot.wav', 'wb') { |f|
    new_wav = wav_bytes.first(44) # First grab the wav header
    d = 44
    while d < wav_bytes.length # then grab 4 byte wav sub chunks
      new_wav += wav_bytes[d, 4].reverse  # and reverse them
      d += 4
    f.write( new_wav ) # write "idiot.wav"
  wr.write([0].body ) # write email attachment into pipe

On to Challenge 20: go away!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s