Last week at DerbyCon 5.0 the CircleCityCon folks had a booth with a challenge, the Challenge of Tiamat’s Eye.
@CircleCityCon: Can you solve the Puzzle of Tiamat's Eye? Visit our booth at @DerbyCon to take the challenge! pic.twitter.com/yJzPvxOQk9— Circle City Con (@CircleCityCon) September 26, 2015
The challenge consisted of the small chest pictured above containing an eye made up of blinking red LEDs. Every 30 seconds the pattern would reset. The content organizers hinted that we would need to record the eye at 60fps in order to capture all of the information we needed. We ended up using a coffee creamer cup as a diffuser over the LEDs to make the difference in the pixels clearer. This resulted in the following recording. Note: we recorded 30 seconds at 60fps, which resulted in a 60 second 30fps recording.
Next we extracted each frame from the video with the following command: (ffmpeg would have worked as well too)
avconv -i VID_20150926_175956.mp4 -r 30 frames/%5d.jpg
This resulted in the following 1800 frames.
After viewing the image thumbnails we observed that the shortest amount of time the LED was either on or off was 3 frames. This means that every 3 frames represents a single bit. Since on some frames the LED was half-light we decided to sample every 3rd frame starting in the middle of each bit to get the best representation.
#! /usr/bin/env python import os from PIL import Image import sys def main(): i = 0 # because os.walk is not sorted, and I'm lazy # ls frames/* > frames.list for l in open("frames.list"): i+=1 if i % 3 == 0: im = Image.open(l.strip()) # sample pixel location r,g,b = im.getpixel((1357,657)) if (r>250): sys.stdout.write('1') else: sys.stdout.write('0') print "" if __name__ == "__main__": main()
The python script above reads every 3rd frame and prints out a 0 or 1 depending on the LED state. This gave us the following binary string.
Our first guess was to convert it to ASCII, however that did not return anything intelligible. Another vague hint provided got us thinking it was 10 bit serial data. A quick search on Google led us to Asynchronous Serial Communication, which after removing the first 20 bits for the header, tells us that there is 8 data bits padded by a start and stop bit. Splitting the binary into 10 bit lines and then removing the first and last bit provided us with the following binary.
01100110 01101001 01110010 01110011 01110100 01110100 01101111 01101100 01101111 01100011 01100001 01110100 01100101 01110100 01101000 01100101 01101000 01101111 01110101 01110011 01100101 01101111 01100110 ...
Converting this to ASCII returns the following text.
After adding a few spaces says:
first to locate the house of bear jester wins a free c3 ticket
which was the magic phrase to say to the house of bear to solve the challenge and win CircleCityCon tickets.
Three worthy adventurers have solved the mystery of the Eye of Tiamat @sid_tracker @lanrat @ryatesm Congrats! pic.twitter.com/O0vMFNiCeb— Circle City Con (@CircleCityCon) September 27, 2015
The puzzle was fun and simple enough to solve in a few hours allowing us to enjoy the rest of DerbyCon. I would like to end by thanking CircleCityCon for creating the challenge and my teammates @SID_tracker and @ryatesm for assisting me in solving the challenge.
All of the data used can be found in This Gist.