Skip to content

Instantly share code, notes, and snippets.

@kevinlondon
Forked from richardmcnamara/google_io_puzzle.py
Created April 24, 2014 02:36
Show Gist options
  • Select an option

  • Save kevinlondon/11239568 to your computer and use it in GitHub Desktop.

Select an option

Save kevinlondon/11239568 to your computer and use it in GitHub Desktop.

Revisions

  1. @richardmcnamara richardmcnamara revised this gist Apr 23, 2014. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions google_io_puzzle.py
    Original file line number Diff line number Diff line change
    @@ -42,9 +42,8 @@ def binary_to_ascii(binary_str):
    # 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'.
    # 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
    @@ -57,8 +56,9 @@ def calculate_shortened_url(i_color_code, o_color_code, secret_code):
    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| with the following method: With 053412 and h81s4h
    # we have 0=h, 1=4, 2=h, 3=1, 4=s, 5=8, thus 012345 = h4h1s8.
    # 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):
  2. @richardmcnamara richardmcnamara revised this gist Apr 23, 2014. 1 changed file with 5 additions and 8 deletions.
    13 changes: 5 additions & 8 deletions google_io_puzzle.py
    Original file line number Diff line number Diff line change
    @@ -9,9 +9,6 @@
    # 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 -->
    @@ -60,13 +57,13 @@ def calculate_shortened_url(i_color_code, o_color_code, secret_code):
    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|.
    # 0-5. Reorder |s| with the following method: With 053412 and h81s4h
    # we have 0=h, 1=4, 2=h, 3=1, 4=s, 5=8, thus 012345 = h4h1s8.

    output = ''
    while len(secret_code) > 0:
    index = int(secret_code[:1])
    for x in range(0,6):
    index = int(secret_code.find(str(x)))
    output += s[index]
    secret_code = secret_code[1:]
    return output


  3. @wblakecaldwell wblakecaldwell revised this gist Apr 23, 2014. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions google_io_puzzle.py
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,8 @@
    #
    # 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.
  4. @wblakecaldwell wblakecaldwell revised this gist Apr 23, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions google_io_puzzle.py
    Original file line number Diff line number Diff line change
    @@ -11,9 +11,9 @@
    # Occasionally, one hits the console-based Google I/O ticket game.
    #
    # Here's what the HTML looks like:
    # <span style="color: #663677">I</span>/<span style="color: #617162">O</span>
    # <span style="color: #386834">I</span>/<span style="color: #317368">O</span>
    # <!-- Still need a hint? http://goo.gl/Eypmp -->
    # </li><!-- 110000 110001 110011 110010 110100 110101 -->
    # </li><!-- 110101 110010 110001 110011 110100 110000 -->
    #

    import httplib2
  5. @wblakecaldwell wblakecaldwell renamed this gist Apr 23, 2014. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions gistfile1.py → google_io_puzzle.py
    Original file line number Diff line number Diff line change
    @@ -21,13 +21,13 @@

    # Given the input binary string (ex: '110011'), return
    # the ASCII character for that value (33): '3'
    def binary_to_ascii(bcd_str):
    def binary_to_ascii(binary_str):
    result = 0
    while len(bcd_str):
    while len(binary_str):
    result *= 2
    if bcd_str[:1] == "1":
    if binary_str[:1] == "1":
    result += 1
    bcd_str = bcd_str[1:]
    binary_str = binary_str[1:]
    return str(unichr(result))

    # Calculate our 6-character code shortener by breaking the "I" and "O"
  6. @wblakecaldwell wblakecaldwell revised this gist Apr 23, 2014. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -47,7 +47,8 @@ def binary_to_ascii(bcd_str):
    # 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'
    # 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)))
  7. @wblakecaldwell wblakecaldwell created this gist Apr 23, 2014.
    106 changes: 106 additions & 0 deletions gistfile1.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,106 @@
    #
    # Google I/O 2014 secret invite code finder
    #
    # Blake Caldwell, 2014
    #
    # 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: #663677">I</span>/<span style="color: #617162">O</span>
    # <!-- Still need a hint? http://goo.gl/Eypmp -->
    # </li><!-- 110000 110001 110011 110010 110100 110101 -->
    #

    import httplib2
    import re

    # Given the input binary string (ex: '110011'), return
    # the ASCII character for that value (33): '3'
    def binary_to_ascii(bcd_str):
    result = 0
    while len(bcd_str):
    result *= 2
    if bcd_str[:1] == "1":
    result += 1
    bcd_str = bcd_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'
    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 = ''
    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)