Skip to content

Instantly share code, notes, and snippets.

@wblakecaldwell
Last active August 29, 2015 14:00
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save wblakecaldwell/11203637 to your computer and use it in GitHub Desktop.
Save wblakecaldwell/11203637 to your computer and use it in GitHub Desktop.
Google I/O secret invite code finder
#
# Google I/O 2014 secret invite code finder
#
# Blake Caldwell, 2014
#
# Blog Post: http://blakecaldwell.net/blog/2014/4/23/solving-a-2014-google-io-secret-invite-puzzle.html
#
# Repeatedly hit https://developers.google.com looking two-colored "I/O" on the page,
# with a secret code in comments below it. Using the color codes of the "I" and "O",
# calculate the 6-character Google URL-shortened link code, and print the code out.
#
# I'm not sure if this is intentional or my mistake, but most of the URLs end up 404.
# Occasionally, one hits the console-based Google I/O ticket game.
#
# Here's what the HTML looks like:
# <span style="color: #386834">I</span>/<span style="color: #317368">O</span>
# <!-- Still need a hint? http://goo.gl/Eypmp -->
# </li><!-- 110101 110010 110001 110011 110100 110000 -->
#
import httplib2
import re
# Given the input binary string (ex: '110011'), return
# the ASCII character for that value (33): '3'
def binary_to_ascii(binary_str):
result = 0
while len(binary_str):
result *= 2
if binary_str[:1] == "1":
result += 1
binary_str = binary_str[1:]
return str(unichr(result))
# Calculate our 6-character code shortener by breaking the "I" and "O"
# color codes into 6 pairings of 2 characters, converting each pairing
# from hex->int, then looking up that ASCII character. Once we have that
# code, rearrange it based on |secret_code|, which is a 6-chracter string
# of integers from 0-6.
#
# For example, given #386834 and #317368, along with 521340:
# 1. Break the color codes into 6 hex digits:
# 0x38, 0x68, 0x34, 0x31, 0x73, 0x68
# 2. Convert each number to decimal
# 56, 104, 52, 49, 115, 104
# 3. Convert these numbers to their ASCII values
# '8', 'h', '4', '1', 's', 'h'
# 4. Reorder the characters by the secret code. Since '5' is the first
# value in the secret code, we'll start with index 5 of the ASCII string,
# 'h'. Next is index 2, or '4'.
# 'h', '4', 'h', '1', 's', '8'
# 5. Return our new code: 'h4h1s8', which produces the valid URL of
# http://goo.gl/h4h1s8
def calculate_shortened_url(i_color_code, o_color_code, secret_code):
s = str(unichr(int(i_color_code[0:2], 16)))
s += str(unichr(int(i_color_code[2:4], 16)))
s += str(unichr(int(i_color_code[4:6], 16)))
s += str(unichr(int(o_color_code[0:2], 16)))
s += str(unichr(int(o_color_code[2:4], 16)))
s += str(unichr(int(o_color_code[4:6], 16)))
# |secret_code| is 6 character string consisting of the integers
# 0-5. Reorder |s| by taking its index at the values of |secret_code|.
# For example, if |secret_code| is '543210', then we're reversing |s|.
output = ''
while len(secret_code) > 0:
index = int(secret_code[:1])
output += s[index]
secret_code = secret_code[1:]
return output
# Our regular expression for finding the color codes for "I" & "O",
# and the commented-out binary strings
regex = re.compile('<span style="color: #([0-9]+)">I</span>/<span style="color: #([0-9]+)">O</span>.+<!-- ([ 01]+) -->', re.DOTALL)
http = httplib2.Http()
# Keep track of what codes we've seen to avoid duplicates
found_codes = {}
while True:
# Fetch the Google Developers page
headers, body = http.request("https://developers.google.com")
# apply the regex to find matches - not all pages have the codes
matches = [m.groups() for m in regex.finditer(body)]
if matches and len(matches[0]) == 3:
# the color code for the "I" in "I/O"
o_color = (matches[0])[1]
# the color code for the "O" in "I/O"
i_color = (matches[0])[0]
# the "secret code", ie: "110000 110001 110011 110010 110100 110101 "
code = (matches[0])[2]
# Break apart the secret code into words, convert each chunk to an integer,
# then join them together to form a 6-character string made up of 0-5.
code_str = ''.join([binary_to_ascii(value) for value in code.split()])
# Given the "I" color, the "O" color, and the secret code, determine
# our 6-character URL-shortener code
shortened_url_code = calculate_shortened_url(i_color, o_color, code_str)
if shortened_url_code not in found_codes:
# we haven't seen this one yet...
found_codes[shortened_url_code] = 1
# print it out - hopefully it's a winner!
print('http://goo.gl/%s' % shortened_url_code)
@yanick76
Copy link

You have bug in calculate_shortened_url.
I don't have any experience with python, but my first try in python is here (feel free to beautify my code):

def calculate_shortened_url(i_color_code, o_color_code, secret_code):
    s = str(unichr(int("0x" + i_color_code[0:2], 16)))
    s += str(unichr(int("0x" + i_color_code[2:4], 16)))
    s += str(unichr(int("0x" + i_color_code[4:6], 16)))
    s += str(unichr(int("0x" + o_color_code[0:2], 16)))
    s += str(unichr(int("0x" + o_color_code[2:4], 16)))
    s += str(unichr(int("0x" + o_color_code[4:6], 16)))

    # |secret_code| is 6 character string consisting of the integers
    #0-5. Reorder |s| by taking its index at the values of |secret_code|.
    # For example, if |secret_code| is '543210', then we're reversing |s|.

    output = ''
    pos = 0

    while len(output) < len(s):

         for i in range(0, len(s)):
            if pos == int(secret_code[i]):
                output += s[i]
                pos += 1

    return output

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment