Barcode Challenge – Part 2

HaD_barcode

Yesterday we issued a barcode challenge in honor of the Barcode’s birthday. Congratulations to [The Moogle] for winning this challenge. His submission offers a very detailed explanation of how he solved the puzzle using Photoshop, OpenOffice Calc, and some web resources. We’ve got a detailed writeup on it after the break.

Honorable mentions go to [nex] for putting up a Java solution and to [jwmaag] for showing a Python solution. Finally, kudos to all who used a CueCat in one way or another to decode the string. Just having one of those still around is pretty hack-it-y.

Because of the ubiquity of Barcode scanners and online image translation programs the challenge might have been a bit too easy. Do you think you’re up for a greater challenge? Download the new barcode and get to work. This one should be quite a bit harder to decipher. Once again, leave a comment that includes the message stored in the Barcode. Please remember, only entries that solve the puzzle and include a full description of the process will be considered. Good luck, and let the games begin.

Update: It only took [JP] 19 minutes to post a correct solution to the new Barcode.  Great work!

[The Moogle’s] winning solution:

pattern_counting_binary

First, [The Moogle] opened up the barcode in Photoshop, zoomed in, and added a grid of lines below to help in reading out the binary code. The red markers were used to help delineate between data chunks.

open_office_calc_binary

The image was then put into a spreadsheet program (OpenOffice Calc in this case) and the binary for each chunk was read out by hand.

the_solution

He formatted the binary in order to make sure he hadn’t made errors, then used a lookup table for code 128 to generate the characters from each data chunk.

Nice work! This solution was executed with tools that everyone has and knows how to use.

40 thoughts on “Barcode Challenge – Part 2

  1. That one was easy. “Smart? Try different languages” The barcode was hex which when translated into ASCII was “Smart? Subukan ang ibang mga wika.” Translate the Subukan ang ibang mga wika from Filipino to English and you get the final string.

  2. i got as far as the fact it was hex ascii and was gonna start doing it but then figured that someone would get it first….. prob not the right attitude.

    I do enjoying them, but perhaps having a secret submission would spurn ppl on to getting it.

  3. Use http://www.onlinebarcodereader.com/ to get the data of the barcode. That gets:
    536D6172743F20537562756B616E20616E67206962616E67206D67612077696B612E

    Looks like Hexadecimal. Use http://www.dolcevie.com/js/converter.html to convert it to text. That gives: “Smart? Subukan ang ibang mga wika.”

    Use http://translate.google.com/translate_t to detect and translate to English, giving: “Smart? Try different languages.” (Translated from Filipino.)

  4. @Mike Szczys
    Still fun to see the rush for an answer… you guys should have some incredibly hard competition for everyone, not saying i would even have the remote chance, but it would be interesting to see people struggle for a few days to find the answer to a simple code, and would get a few bizzare, crazy solutions.

  5. Yeah it was fun even though once I saw the post it took about 2 minutes to get the answer. Easy doesn’t necessarily mean un-enjoyable. That being said, a harder one would be nice. :)

  6. UGH I worked so hard on this and you guys got it so fast. i feel dumb ;_;

    I used mspaint to count the pixels, similar to the previous contests method. Then I decoded the binary string with code-128, again like the previous contest. it looked like gibberish so i was about to try another encoding, when i noticed there were a lot of 6’s. i converted hex to ascii and got

    Smart? Subukan ang ibang mga wika.

    That second part looked like gibberish so I tried to solve it like a cryptoquip, only to fail miserably. I looked up the individual words and got results for Filipino Dictionary. So I translated it and got

    Smart? Try different languages.

    maybe i’m a little out of my league

  7. I have a good idea why don’t we set up a decode-athon. instead of these short and easy challenges. just put a bunch of different languages with different messages and see who deciphers them first.

  8. you and the google can make it happen!
    googled barcode decoder
    2nd result:
    http://zxing.org/w/decode.jspx
    submitted picture of barcode
    received string of hex
    536D6172743F20537562756B616E20616E67206962616E67206D67612077696B612E
    googled hex converter
    1st result:
    http://home2.paulschou.net/tools/xlate/
    pasted string into “hex” box, converted
    Smart? Subukan ang ibang mga wika.
    result in text
    typed “google translate” in chrome address bar
    http://translate.google.com/translate_t#
    detect language, paste “Smart? Subukan ang ibang mga wika.”
    result:
    Smart? Try different languages.

  9. There used to be a wargames site called dievo.org that was very very thorough, teaching the basics of research up to live shell wargames where to make it from level to level you needed to exploit a binary that ran as the next level’s user and coerce it to give you a shell.

    Hackaday should try to contact the site owner and get it back up and running. It was seriously the greatest computer security education I’ve ever gotten, and I have a bachelors degree in computer science with a specialization in information security.

  10. oh, i didn’t even think about a hex converter. crap.

    536D6172743F20537562756B616E20616E67206962616E67206D67612077696B612E

    IS

    Smart? Subukan ang ibang mga wika.

    IS

    Smart? Try different languages.

    there we go. i lose

  11. The answer in one URL:
    http://translate.google.com/translate?sl=tl&tl=en&u=http://test.alapetite.fr/hex2txt.php?url=http://zxing.org/w/decode?u=http://hackaday.com/wp-content/uploads/2009/10/barcode_challenge_part_2.jpg
    I wanted to have a solution entirely “in the cloud” using a link of different Web services for each functions (one function at a time). But I failed to find a hexadecimal-to-text Web service that takes a URL as a GET parameter (so I have made a temporary one on my own server). Furthermore, due to the word “smart”, the automatic language detection of Google is not working.
    So not a very cool answer in the end :-(

  12. You can also get the binary string encoded in the image using imagemagick (convert barcode_challenge_part_2.jpg -crop 800×1+0+99 barcode_challenge_part_2.pbm), and get it printed to the screen by means of od (with something like od -j74 -x barcode_challenge_part_2.pbm | cut -d’ ‘ -f2-). Then you could apply the decoding algorithm.
    Of course it’s one hell of a job.

  13. Again, I used the python script I wrote for the last challenge, just substituting the old url, with the new one:

    #############
    import cStringIO, urllib, Image

    bin = [‘11011001100′,’11001101100′,’11001100110′,’10010011000′,’10010001100’,
    ‘10001001100’,’10011001000′,’10011000100′,’10001100100′,’11001001000′,
    ‘11001000100’,’11000100100′,’10110011100′,’10011011100′,’10011001110′,
    ‘10111001100’,’10011101100′,’10011100110′,’11001110010′,’11001011100′,
    ‘11001001110’,’11011100100′,’11001110100′,’11101101110′,’11101001100′,
    ‘11100101100’,’11100100110′,’11101100100′,’11100110100′,’11100110010′,
    ‘11011011000’,’11011000110′,’11000110110′,’10100011000′,’10001011000′,
    ‘10001000110’,’10110001000′,’10001101000′,’10001100010′,’11010001000′,
    ‘11000101000’,’11000100010′,’10110111000′,’10110001110′,’10001101110′,
    ‘10111011000’,’10111000110′,’10001110110′,’11101110110′,’11010001110′,
    ‘11000101110’,’11011101000′,’11011100010′,’11011101110′,’11101011000′,
    ‘11101000110’,’11100010110′,’11101101000′,’11101100010′,’11100011010′,
    ‘11101111010’,’11001000010′,’11110001010′,’10100110000′,’10100001100′,
    ‘10010110000’,’10010000110′,’10000101100′,’10000100110′,’10110010000′,
    ‘10110000100’,’10011010000′,’10011000010′,’10000110100′,’10000110010′,
    ‘11000010010’,’11001010000′,’11110111010′,’11000010100′,’10001111010′,
    ‘10100111100’,’10010111100′,’10010011110′,’10111100100′,’10011110100′,
    ‘10011110010’,’11110100100′,’11110010100′,’11110010010′,’11011011110′,
    ‘11011110110’,’11110110110′,’10101111000′,’10100011110′,’10001011110′,
    ‘10111101000’,’10111100010′,’11110101000′,’11110100010′,’10111011110′,
    ‘10111101110’,’11101011110′,’11110101110′,’11010000100′,’11010010000′,
    ‘11010011100’,’1100011101011′
    ]

    val = [‘ ‘, ‘!’, ‘”‘, ‘#’, ‘$’, ‘%’, ‘&’, ‘\”,
    ‘(‘, ‘)’, ‘*’, ‘+’, ‘,’, ‘-‘, ‘.’, ‘/’,
    ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’,
    ‘8’, ‘9’, ‘:’, ‘;’, ”, ‘?’,
    ‘@’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’,
    ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’,
    ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’,
    ‘X’, ‘Y’, ‘Z’, ‘[‘, ‘\\’, ‘]’, ‘^’, ‘_’,
    ‘`’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’,
    ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’,
    ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’,
    ‘x’, ‘y’, ‘z’, ‘{‘, ‘|’, ‘}’, ‘~’, ‘DEL’,
    ‘FNC3’, ‘FNC2’, ‘SHIFT’, ‘Code C’, ‘FNC4’, ‘Code A’,
    ‘FNC1’, ‘START A’, ‘START B’, ‘START C’, ‘STOP’
    ]

    def parsePixel(pix):
    r, g, b = pix
    if r + g + b > 500:
    return 0
    else:
    return 1

    def parseChar(ch):
    for i in range(len(bin)):
    if ch == bin[i]:
    return i
    return -1

    def parseImage(name):
    i = Image.open(img)
    count = -1
    char = “”
    for a in range(i.size[0]):
    pixel = parsePixel(i.getpixel((a, i.size[1]/2)))
    if count == -1 and pixel == False:
    continue
    elif count == -1:
    count = 0
    count += 1
    char += str(pixel)
    if count >= 11:
    num = parseChar(char)
    if num == -1:
    continue
    print val[num],
    if num == 106:
    return
    char = “”
    count = 0

    fp = urllib.urlopen(‘http://hackaday.com/wp-content/uploads/2009/10/barcode_challenge_part_2.jpg’)
    img = cStringIO.StringIO(fp.read())
    parseImage(img)
    ################

    this gave me:
    “(START B) 536D6172743F20537562756B616E20616E67206962616E67206D67612077696B612E-
    (STOP)”

    Another python script:
    #######################
    import binascii
    print binascii.a2b_hex(“536D6172743F20537562756B616E20616E67206962616E67206D67612077696B612E”)
    ################

    gave me:
    “Smart? Subukan ang ibang mga wika.”

    Googling ‘subukan’ brought me to this page:
    http://www.imdb.com/title/tt0399165/combined
    from which I understood that the language was Filipino.

    Google translate then translated the last part for me:
    “Try different languages.”

    Thus the final answer is:
    “Smart? Try different languages.”

  14. I keep missing the posts for these challenges lol, but I think doing this kind of “challenge the audience” thing makes hackaday more interactive.

    I like it, and for the most part agree with Nikropht- It would definitely be a plus, but prize or not.

  15. 1)On cursory examination, the code is black and white.
    2)It appears the information is encoded horizontally, therefor (using GIMP) crop the picture down to a single row of black and white pixels.
    3)Assign the color of negative space around the code – white – a value of 0, and the black valued pixels making up the positive space a value of 1.
    4)Assume that the code does not begin with whitespace. Crop leading and trailing zero valued pixels.
    5)Code is now 783 bits long. Bits will be referred to from left to right, bit 1 to bit 783. Assume each letter is encoded in the same length of bits. 783 can be (using a pocket calculator) factored to the following pairs:
    783=(3*3*3*29)
    3 letters of length 261
    9 letters of length 87
    27 letters of length 29
    29 letters of length 27
    87 letters of length 9
    261 letters of length 3
    6)Break into lengths of letters. Assume that no letter begins with whitespace. Assume the code is meant to be machine readable with simple technology, therefor each letter should begin with a binary value, and end in its complement. The code begins with 1, so assume each letter should end in 0. The code does not work for the above letter bit-lengths, therefor some sort of start or stop code is being utilized, i.e., the code is less than 738 bits long.
    7)Perform cursory analysis of length between “0,1” pairs in code starting from beginning.
    3, 6, 11, 14, 19, 22, 26, 28, 33, 37, 41, 44, 46, 51
    + + + +
    Code appears to have breaks every 11 bits. Check 55 and 99 to examine hypothesis.

    10001 | 00101
    5 | 9
    5 | 9
    + | +

    _8_) Recap: Shrink picture to managable image of code, vector with 783 values. 783’s factors do not point to simple code, so check for patterns to decide letter length. “01” occurs every 11th bit, so work from that.

    9)Highest multiple of 11 less than 783 is 781. This suggest that the last two bits are a stop code. Bits 781, 782, and 783 are “011” which would indicate a stop code of “11.” Proceed assuming 11 bit letters.
    10)(Using GIMP) convert image to 1 bit pallette. Since most computer graphics use additive color mixing, invert values of the bitmap. Save image as “barcode2.c” (Filetype: C source code) in order to open in a text editor in human readable fashion. Heed warning that plugin must convert to RGB for export.
    11)Open “barcode2.c” in a text editor. Ignoring possible knowledge of the C programming language, it is trivial to see that the image data is stored in a series of “/377″s and “/0” between quotes. Delete the text before and after this series of values.
    12)Using the text editor’s functionality, delete every instance of quotation marks, all white space, and all {NEWLINE} characters.
    13)Observe that the first 11 bits of our code are “11010010000” but the first 11 values in our text file are “\377\377\377\377\377\377\377\377” or “11111100011”. Remember the warning we heeded earlier; exported images will be encoded in RGB color depth. Each bit of our code is stored as “\377\377\377” = “1” and “” = “0”.
    14)Using the text editor’s text substitution function, translate the code to 1’s and 0’s.
    15)Observe that the first 11 bits of our text are “11010010000” as expected.

    _16_) Recap: Using basic functionalities of GIMP and a text editor, translate the code into easily manipulated and simplified text, as opposed to an unwieldly graphic.

    17)Using the text editor, break the code into 11 bit “letters.”
    18)Each letter begins with “1” and ends with “0”, and there are two “1”s left over at the end. Our hypothesis of 11 bit letters is reinforced.
    19)Substitute “A” for every instance of the first 11-bit letter. Likewise “B” and every instance of “101110010”, and continue through the code until it is simplified to single characters.

    ABCDEDFGHGICJHKBCGBDHGBDLDFDMHKDFDMDGHKDNDHDFDMDGHKDEDGDFHKGGDNDLDFHMOP

    20)Intuitively substitute letters to find patterns. There are 16 unique “letters” encoded, some of which might be markup or non-alphabet symbols – numbers, punctuation, etc. – so grind away at it.
    e for most common letter (D)? looks weird.
    {SPACE} for most common letter (D)? Thirteen single letter words, one thirteen letter word… clue?
    e for G. It’s the only double in the code…

    21)oy.

    22)Give up on find and replace. Cheat and search for “11010010000” on google, hit “I’m Feeling Lucky”. If this doesn’t work, give up altogether.
    23)I, in fact, am lucky.

    _24_) Recap: Find the codetext. Cheat.

    25)Using (the source of) http://svn.schooltool.org/cando/branches/barcode/src/cando/barcode/code128_barcode.py translate a few “letters” and see if that’s enough of a clue. Will start with A, G, D, and H.
    26)A = {START B}, D = “6”, G = “7”, H = “2”. Assuming double substitution. since this will probably remove the patterns I could see, translate by han– wait!
    27)In sorting the 11 bit letters in order to simplify translation, I again notice the 16 unique letters. Since the first four I translated were numbers and a start code, I assume HEX encoding. Our problem now simplifies itself from:
    ABCDEDFGHGICJHKBCGBDHGBDLDFDMHKDFDMDGHKDNDHDFDMDGHKDEDGDFHKGGDNDLDFHMOP
    to
    {START B} BC 6E 6F 72 7I CJ 2K BC 7B 62 7B 6L 6F 6M 2K 6F 6M 67 2K 6N 62 6F 6M 67 2K 6E 67 6F 2K 77 6N 6L 6F 2M OP
    to (The “+” appears due to a transcription error. The code is still valid, as the symbols in place are meaningless and were just shifted to not interfere with HEX notation.)
    {START B} MN 6P 6Q 72 7T NU 2V MN 7M 62 7M 6W 6Q 6+ 2V 6Q 6+ 67 2V 6X 62 6Q 6+ 67 2V 6P 67 6Q 2V 77 6X 6W 6Q 2+ YZ
    to (knowing that lowercase a is 0x61)
    {START B} MN 6P 6Q r 7T NU 2V MN 7M b 7M 6W 6Q 6+ 2V 6Q 6+ g 2V 6X b 6Q 6+ g 2V 6P g 6Q 2V w 6X 6W 6Q 2+ YZ
    or (knowing lowercase letters go from 0x61 TO 0x7A)
    ___r_____b_______g__b__g__b__w_____
    to (2V is common and has the right digit in the 16’s place for {SPACE})
    ___r__ __b____ __g _b__g _g_ w_____
    to (MN, NU, YZ are either Capitals or punctuation. NU {SPACE} MN suggests that MN is a capital letter, so M is either 5 or 4. test a few letters)
    M=5 => _ubu___. possible, but strange.
    M=4 => _tbt___. doubt it.
    5N 6P 6Q r 7T NU 2V 5N 75 b 75 6W 6Q 6+ 2V 6Q 6+ g 2V 6X b 6Q 6+ g 2V 6P g 6Q 2V w 6X 6W 6Q 2+ YZ
    5N 6P 6Q r 7T NU 5N u b u 6W 6Q 6+ 6Q 6+ g 6X b 6Q 6+ g 6P g 6Q w 6X 6W 6Q 2+ YZ
    to (NU and YZ are punctuation. U and Z are 0xE, 0xF, or 0x1. N and Y are 2 or 3. starts with 0x52 or 0x53, “R” or “S”)
    N=2 R__r_! or R__r_. | Roars Rears | Rubu___
    N=3 S__r_? | Store? Stork? Spork? Smart? | Subu___
    What is being used? 0, 2, 5, 6, 7
    N can’t be 2, so N=3.
    53 6P 6Q r 7T 3U 53 u b u 6W 6Q 6+ 6Q 6+ g 6X b 6Q 6+ g 6P g 6Q w 6X 6W 6Q 2+ YZ
    to
    S 6P 6Q r 7T 3U S u b u 6W 6Q 6+ 6Q 6+ g 6X b 6Q 6+ g 6P g 6Q w 6X 6W 6Q 2+ YZ
    or
    S__r__ Subu___ __g _b__g _g_ w_____
    Terminal punctuation with 3 in the 16s place has to be “?”
    S__r_? Subu___ __g _b__g _g_ w_____
    U = 0xF
    What is being used? 0, 3, 2, 5, 6, 7, F
    28)Sleep on it.
    29)First word is “Smart? ” since 6P and 6Q have to be from the first 16 letters of the alphabet. P=0xD, Q=0x1, T=4.
    S 6D 61 r 74 3U S u b u 6W 61 6+ 61 6+ g 6X b 61 6+ g 6D g 61 w 6X 6W 61 2+ YZ

    What is being used? 0, 2, 5, 6, 7, F, D, 1

    30)Realize that the 16 unique values that inspired to use HEX doesn’t really follow, since one was a START CODE. Feel lucky still.
    31)S m a r t ? S u b u 6W a 6+ a 6+ g 6X b a 6+ g m g a w 6X 6W a 2+ YZ

    Smart? Subu 6W a 6+ a 6+ g 6X ba 6+ g mga w 6X 6W a 2+ YZ

    YZ appears to be a stop code, since 2+ is punctuation, and it doesn’t have an open quote or anything like that earlier. We also have a complete word. Probably triple substitution. I hope not. Maybe it means something. If it’s another substitution code, I don’t want to play.

    W, +, X need decoding. 0, 1, 2, 3, 4, 5, 6, 7, D, F being used.
    2+ is terminal punctuation, either “.” or “!”, plus either 0xE or 0x1, 1 is in use, so + = E
    Smart? Subu 6W a 6E a 6E g 6X ba 6E g mga w 6X 6W a 2E

    Smart? Subu6Wang 6Xbang mga w6X6Wa.
    0, 1, 2, 3, 4, 5, 6, 7, D, E, F being used. W and X are 8, 9, A, B, or C
    random subbing.
    Smart? Subuhang ibang mga wiha.
    looks familiar, google search for word that is definite, “mga”. Nothing. Not an abbreviation, since there are capital letters… searching other random words.
    Subuhang = lots of asian stuff.
    ibang = 11th result down on google says “…this is Tagalog…” so I’ll pop it in a translator and see what comes out.
    Google doesn’t have a Tagalog translator, but a google search for “Tagalog translator” gives the info that it’s the Phillipines national language… No Reservations: Phillipines on Tivo while I was working on this. No lie. Google translate from Fillipino to English:
    Smart? Subuhang other wiha.
    The “i” is correct, X = 9, but Subuhang doesn’t translate. Trying A, B, and C
    Smart? Subu6Wang ibang mga wi6Wa.
    Smart? Subujang ibang mga wija. = Smart? Subujang other wija.
    Smart? Subukang ibang mga wika. = Smart? Try other languages.
    Smart? Subulang ibang mga wila. = Smart? Subulang other wila.

    _32_) Recap: Kind of like a Sudoku from Hell. Sub letters until it starts making a little sense, and then just go with it. keep track of what you’ve eliminated. Same general feeling as a Legend of Zelda puzzle. hmm.

    -33-) Looks like the bar code translates to “Smart? Try other languages.” Whether that means I should continue to work on the code, I don’t know. But I think I’m done.

  16. Took a similar process. luckily you stuck with 128B and didn’t change the code-set in the middle of the barcode ( i would have to make new lookup tables, bleh )

    after looking at the string I got…
    “536D6172743F20537562756B616E20616E67206962616E67206D67612077696B612E”

    it looked like it was made of hex, like Hakon i used binascii in python and got
    “Smart? Subukan ang ibang mga wika.”

    then used google translate from there…
    nice challenge.

  17. @Mike Szczys
    Unfortunately, as you can see, I cheated by trusting my luck to google and looking up four of the 11 bit letters. In hindsight, I wish I hadn’t, but I don’t think I would have gotten it otherwise. Thank you so much for your kind words!

  18. An enthusiastic seconding of bringing dievo.org’s wargames back! Digital Evolution’s forums were a fount of info; Norse & co. were very generous with their time and energy, and the wargames were beyond compare. Norse & co. have moved on, the forums are lost to the sands of time, but it would be amazing to see those wargames running somewhere again.

    For those who weren’t lucky enough to have played there, they ran the gamut from crypto to vulnerability exploitation (metasploit wouldn’t help you!) to riddle/puzzles. Most wargames went by levels, so before you could (for example) try your hand at heap-smashing, you had to successfully smash the stack.

  19. Private Sub Form_Load()
    st = “536D6172743F20537562756B616E20616E67206962616E67206D67612077696B612E”
    For n = 1 To Len(st) Step 2
    strMyHexNum = “&H” & Mid(st, n, 2)
    lngdecimalvalue = Val(strMyHexNum)
    Debug.Print (Mid(st, n, 2)), lngdecimalvalue, Chr(lngdecimalvalue)
    Next n
    End Sub

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.