GCHQ Quiz Grinch: 2

***Contains spoilers, obviously.***

As I mentioned previously, the GCHQ (Government Communications Headquarters) released a hilariously infuriating Christmas card, which consisted of a logic puzzle, which once solved, led to more puzzles, which led to more puzzles, and so on. I cheated to complete Part 2. And, here’s how you can cheat to complete Part 4.

Part 4 consists of three series of numbers. These numbers, back to back, create an IP address to access Part 5. Three numbers to make one IP address. Hmmm, an IP address contains four numbers. One of the numbers must be a decimal. So, I’m looking for two integers and one float, but I’m not sure which.

If you look at the source code, there is a hash function that is used to verify that the answers are correct. Basically, it concatenates the three inputs, performs some one-way computations, returns two answers, and checks if they match two other, known numbers. So, you could work out the correct answers (if you’re smart enough), ooooooooor you could try all possible answers (which is what I did).

There are a few ways to constrain the list of possible answers, which will cut down on the computation time. All IP address components are integers between 0 and 255. Also, I took a guess that the first component was between 0-128 – a Class A IP address. The hash function takes 3 inputs, separated by null characters (“\0”). That means I need to separate 4 integers by two null characters and one period (representing a decimal), but I don’t know in which place the decimal should be. There are three possibilities for that.

So, in all, there are 128 * 256 * 256 * 256 * 3 possibilities (first, second, third, fourth IP components, and decimal placements) to inspect. That’s a grand total of 6,442,450,944 combinations to evaluate. Even for Python, that’s a lot of comparisons, but it can be done. It takes about 0.115s to run 128*3 comparisons, about 29.5s to run 128*256*3 comparisons. To complete our six billion comparisons, it will take approximately 22.5 days. Luckily, the final answer is located fairly early in the sequence, so the final run time is about 8.7 days.

Here’s the script I used:

import ctypes, sys, cProfile

def hsh(dat):
    resultA = 3141592654
    resultB = 1234567890
    for i in range(2):
        initA = resultA
        initB = resultB
        for j in range(len(dat)):
            resultA += ord(dat.lower()[j])
            resultB = ctypes.c_int((resultA * 31) ^ resultB).value
            tmp = resultA & resultA
            resultA = resultB & resultB
            resultB = tmp
        resultA = ctypes.c_int(resultA ^ initA).value
        resultB = ctypes.c_int(resultB ^ initB).value
    return [resultA, resultB]

dot_config = [['.','\0','\0'],['\0','.','\0'],['\0','\0','.']]

def findIP():
    for x in range(128):
        for y in range(256):
            for z in range(256):
                for a in range(256):
                    for dots in dot_config:    
                        res = hsh("".join([str(x), dots[0], str(y), dots[1], str(z), dots[2], str(a)]))
                        if (res[0]==1824745082) and (res[1]==560037081):
                            print ([str(x), dots[0], str(y), dots[1], str(z), dots[2], str(a)])
                            sys.exit()
            print (x, y, z, a, res[0], res[1])
    
cProfile.runctx('findIP()',None,locals())

 

And, the final answers: 52, 30.87, 208

The quiz is for charity, so don’t forget to donate here.

GCHQ Quiz Grinch: 1

***Contains spoilers, obviously.***

The GCHQ (Government Communications Headquarters) released a hilariously infuriating Christmas card, which consisted of a logic puzzle, which once solved, led to more puzzles, which led to more puzzles, and so on.

I solved the first puzzle no problem. That revealed Part 2, a series of 6 multiple choice questions, all of which required a correct answer to move on. I got two of them, but was left at a loss for the other four. I gave it an honest try, but really wanted to see what Part 3 had in store. So, I turned to cheating. And, here’s how.

Clicking through the answers, you may notice that the URL contains the previous answer letter. For example, if your answers were A, B, C, D, E, and F, the final webpage (telling you that you were wrong) would have the URL: http://s3-eu-west-1.amazonaws.com/puzzleinabucket/ABCDEF.html

If you had enough time, you could type in each combination and see if that led to a “correct” URL. Obviously, that would be fairly time-consuming. Each of 6 questions had 6 possible answers, which means 6 ^ 6 = 46656 possibilities. You could save some time by including known correct answers. In my case, I had two answers of which I was confident. That left me with 6 ^ 4 = 1296 possibilities, still too many to inspect manually.

However, a simple Python script could load the pages fairly quickly (about once per second, or a maximum of 21.6 minutes), inspect the resulting webpage, and determine if it contains a message indicating that the combination was incorrect. If so, move onto next combination. If not, stop and print the correct combination.

Here’s the script:

import requests, time, sys
from lxml import html

opts = ['A','B','C','D','E','F'] # possible answers
for i in opts:
    for j in opts:
        for k in opts:
            for l in opts:
                url = i + j + k + 'A' + l + 'E' # 4 unknown, 2 known
                time.sleep(1) # provide rest in between calls
                
                r = requests.get('http://s3-eu-west-1.amazonaws.com/puzzleinabucket/' + url + '.html') # make call
                tree = html.fromstring(r.text) # store page html
    
                if tree.xpath('//div[contains(., "Sorry - you did not get all the questions correct.")]/p//text()'):
                    pass
                else:
                    print "SUCCESS " + url
                    sys.exit() # quit script once correct combination is found

 

And the final answer: DEFACE

The quiz is for charity, so don’t forget to donate here.

 

3D Prince George Buildings Map

pg_buildings

I’ve been working through some of the demos for Cesium JS (a JavaScript library for creating 3D maps), and came across this one demonstrating how to display the buildings of Nanaimo.

I was curious to see if the data exists for Prince George, BC, and it turns out, it does (PG Open Data Catalogue, buildings download)! I’m not 100% sure if this dataset was created manually or through automation, but I’m impressed with the level of detail.

The method I used to make this map* is actually shockingly simple. I downloaded the shapefile, saved it as GeoJSON in QGIS, and uploaded it to my server. Then, the JavaScript on the webpage incorporates Cesium, loads the geometry data from the GeoJSON, adds heights from the buildings’ attributes list, and sets the camera view. That’s how easily you can make a pretty neat looking 3D map of Prince George.

*note: there are over 30,000 buildings in this dataset. It takes about 30 seconds to load, for me. It may not work on your mobile devices.

what3words Poetry

w3w_poem

I’ve been seeing lots of buzz about what3words (w3w), an intriguing addressing system that assigns a combination of three words to every 3m x 3m square on Earth. For example, you can find the center of LSU Tiger Stadium at upward.searcher.superstar. w3w’s API toggles 3-word addresses with lat/long coordinates, so you can actually locate the address (one of the, I assume necessary, annoyances of w3w addresses is that the words are random, so you have no information about adjacent addresses based on a known address).

As a completely useless example of how you can use the w3w API, I present w3w Poems. Following the rules found here for creating a 3-word poem for Ms.Guillory’s 5th grade classroom at Gardner Pilot Academy in Allston, Massachusetts, the user is presented with a random w3w address, which is the first line of the poem. The last two words become the first two words on the next line. The user enters a third word. If it completes a new w3w address, the user is whisked away to the location, the poem line completes, and a new partial poem line is presented. The user repeats until they decide the poem is complete.

Enjoy!

FYI: There’s a whole blog about w3w inspired poetry.

SEC Cross-divisional Games Diagram

sec_ncWhile watching some uninspiring NCAA football games today (I’m looking at you, OSU/Michigan and Georgia/Vanderbilt), I had a chance to wonder about this year’s SEC cross-divisional games. Each year, each SEC team plays two games against teams in the opposite division (i.e. each SEC West team plays two SEC East opponents).

Here is a diagram showing who’s playing who in 2015.