HITB GSEC 2017 / Published

2017, Dating in Singapore

Reading a string of digits as twelve months of days and tracing them out on the 2017 calendar.

misc

3 min read

Challenge brief

01081522291516170310172431-050607132027162728-0102030209162330-02091623020310090910172423-02010814222930-0605041118252627-0203040310172431-0102030108152229151617-04050604111825181920-0108152229303124171003-261912052028211407-04051213192625

Interpreting the digits as calendar dates

In this challenge, we are only given the above string of characters and nothing else. The word Dating in the title could imply that this challenge has something to do with couples, or it could refer to calendar dates. Since they took the liberty of specifically including the year 2017 in the title, one can only assume that we should be adopting the latter definition.

Text
In [1]: data = '''01081522291516170310172431-050607132027162728-010203020916
   ...: 2330-02091623020310090910172423-02010814222930-0605041118252627-0203
   ...: 040310172431-0102030108152229151617-04050604111825181920-01081522293
   ...: 03124171003-261912052028211407-04051213192625'''

In [2]: len(data.split('-'))
Out[2]: 12

The first observation we made is that we get exactly 12 chunks if we split the string of characters using - as the delimiter. This is very convenient given the definition of Dating that we chose to adopt. There are 12 chunks, and there are (conveniently) 12 months in a year.

Text
In [3]: data = data.split('-')

In [4]: print [map(''.join, zip(*[iter(x)]*2)) for x in data]
[['01', '08', '15', '22', '29', '15', '16', '17', '03', '10', '17', '24', '31'], ['05', '06', '07', '13', '20', '27', '16', '27', '28'], ['01', '02', '03', '02', '09', '16', '23', '30'], ['02', '09', '16', '23', '02', '03', '10', '09', '09', '10', '17', '24', '23'], ['02', '01', '08', '14', '22', '29', '30'], ['06', '05', '04', '11', '18', '25', '26', '27'], ['02', '03', '04', '03', '10', '17', '24', '31'], ['01', '02', '03', '01', '08', '15', '22', '29', '15', '16', '17'], ['04', '05', '06', '04', '11', '18', '25', '18', '19', '20'], ['01', '08', '15', '22', '29', '30', '31', '24', '17', '10', '03'], ['26', '19', '12', '05', '20', '28', '21', '14', '07'], ['04', '05', '12', '13', '19', '26', '25']]

In [5]: data = [map(''.join, zip(*[iter(x)]*2)) for x in data]

In [6]: print sum(data, [])
['01', '08', '15', '22', '29', '15', '16', '17', '03', '10', '17', '24', '31', '05', '06', '07', '13', '20', '27', '16', '27', '28', '01', '02', '03', '02', '09', '16', '23', '30', '02', '09', '16', '23', '02', '03', '10', '09', '09', '10', '17', '24', '23', '02', '01', '08', '14', '22', '29', '30', '06', '05', '04', '11', '18', '25', '26', '27', '02', '03', '04', '03', '10', '17', '24', '31', '01', '02', '03', '01', '08', '15', '22', '29', '15', '16', '17', '04', '05', '06', '04', '11', '18', '25', '18', '19', '20', '01', '08', '15', '22', '29', '30', '31', '24', '17', '10', '03', '26', '19', '12', '05', '20', '28', '21', '14', '07', '04', '05', '12', '13', '19', '26', '25']

In [7]: print set(sum(data, []))
set(['30', '04', '24', '03', '26', '01', '20', '07', '22', '05', '08', '09', '28', '29', '02', '25', '27', '06', '21', '11', '10', '13', '12', '15', '14', '17', '16', '19', '18', '31', '23'])

In [8]: print sorted(set(sum(data, [])))
['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31']

Tracing the dates on the 2017 calendar

After manipulating the data further, we made an additional observation that the characters in each chunk, when interpreted as a series of two digit integers, all lie within the range 1 to 31. Once again, conveniently for us, that range corresponds to the number of days in a month. Now here’s where we have to get creative. What’s the best way to consolidate all this information? Perhaps let’s try to use the calendar for year 2017.

Reading each chunk as days of its month and joining consecutive days on that month’s calendar draws one character per month. A jump to a day that is not next to the previous one starts a new stroke.

The January and February chunks traced on Sunday-first 2017 calendarsJanuary 2017 starts on a Sunday: 01 08 15 22 29 runs down the Sunday column, 15 16 17 crosses the third week and 03 10 17 24 31 runs down the Tuesday column, drawing H, with 15 and 17 visited twice. February starts on a Wednesday: 05 06 07 crosses the second week, steps diagonally to 13 and runs down the Monday column to 27, and 27 28 extends the base. Day 16, a Thursday, sits alone between two jumps and becomes the dot beside the I.January 2017, weeks start on SundayFebruary 201701081522291516170310172431050607132027162728123123SMTWTFSSMTWTFS245679111213141819202123252627283012348910111214151718192122232425261381015161722242931567131620272816 stands alone: the dot beside the I
Figure 1. Joined in order on a Sunday-first 2017 calendar, January's days draw H. In February, 16 sits between two jumps, so it becomes the lone dot beside the I.
The days in each chunk traced out on the 2017 calendar, spelling the flag

As seen above, the flag can be seen (albeit with a stray dot beside the I) when we trace out the days in the chunks.

Result

Flag: HITB{CTFFUN}