-
-
Save richardmcnamara/11209161 to your computer and use it in GitHub Desktop.
Modify permutation function.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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. | |
# | |
# 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 '0' and 'h' line up, 'h' is the first | |
# value in the secret code. Move through '1'='4' and so on until we get | |
# '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("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 first taking the character which is at the | |
# same index as 0 in |secret_code|, then the same index as 1 and | |
# so on. | |
output = '' | |
for x in range(0,6): | |
index = int(secret_code.find(str(x))) | |
output += s[index] | |
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment