diff --git a/day14/day14 b/day14/day14 new file mode 100755 index 0000000..9a49d31 Binary files /dev/null and b/day14/day14 differ diff --git a/day14/main.go b/day14/main.go new file mode 100644 index 0000000..295bbf9 --- /dev/null +++ b/day14/main.go @@ -0,0 +1,82 @@ +package main + +import ( + "crypto/md5" + "fmt" + "log" + "os" + "strconv" + "strings" +) + +var hashStore []string +var salt string + +func main() { + if len(os.Args) < 3 { + fmt.Println("Usage: ./day14 ") + fmt.Println(" My input: ./day14 cuanljph 64") + os.Exit(1) + } + salt = os.Args[1] + keyNum := atoi(os.Args[2]) + var foundKeys []string + tryIdx := 0 + for len(foundKeys) < keyNum { + tst := getHash(tryIdx) + for i := range tst { + if len(tst) > i+3 { + if tst[i:i+3] == strings.Repeat(string(tst[i]), 3) { + // Found a triple, search the next 1000 for a quintuple + if searchForQuint(salt, tryIdx+1, string(tst[i])) { + foundKeys = append(foundKeys, tst) + } + // Once we test the first triplet, we're done with this one + break + } + } + } + tryIdx++ + } + fmt.Println("Key:", getHash(tryIdx-1), "Idx:", tryIdx) +} + +func getHash(idx int) string { + for len(hashStore)-1 < idx { + hashStore = append( + hashStore, + getStretchedHash(fmt.Sprintf("%x", md5.Sum([]byte(salt+itoa(len(hashStore)+1))))), + ) + } + return hashStore[idx] +} + +func getStretchedHash(s string) string { + for i := 0; i < 2016; i++ { + s = fmt.Sprintf("%x", md5.Sum([]byte(s))) + } + return s +} + +func searchForQuint(salt string, startIdx int, srch string) bool { + for i := startIdx; i <= startIdx+1000; i++ { + tst := getHash(i) + if strings.Contains(tst, strings.Repeat(srch, 5)) { + return true + } + } + return false +} + +func atoi(i string) int { + var ret int + var err error + if ret, err = strconv.Atoi(i); err != nil { + log.Fatal("Invalid Atoi") + } + return ret +} + +func itoa(i int) string { + return strconv.Itoa(i) +} diff --git a/day14/problem b/day14/problem new file mode 100644 index 0000000..5bccbba --- /dev/null +++ b/day14/problem @@ -0,0 +1,89 @@ +Advent of Code + +--- Day 14: One-Time Pad --- + + In order to communicate securely with Santa while you're on this mission, you've been using a one-time pad that you generate using a pre-agreed algorithm. + Unfortunately, you've run out of keys in your one-time pad, and so you need to generate some more. + + To generate keys, you first get a stream of random data by taking the MD5 of a pre-arranged salt (your puzzle input) and an increasing integer index (starting with 0, + and represented in decimal); the resulting MD5 hash should be represented as a string of lowercase hexadecimal digits. + + However, not all of these MD5 hashes are keys, and you need 64 new keys for your one-time pad. A hash is a key only if: + + • It contains three of the same character in a row, like 777. Only consider the first such triplet in a hash. + • One of the next 1000 hashes in the stream contains that same character five times in a row, like 77777. + + Considering future hashes for five-of-a-kind sequences does not cause those hashes to be skipped; instead, regardless of whether the current hash is a key, always + resume testing for keys starting with the very next hash. + + For example, if the pre-arranged salt is abc: + + • The first index which produces a triple is 18, because the MD5 hash of abc18 contains ...cc38887a5.... However, index 18 does not count as a key for your one-time + pad, because none of the next thousand hashes (index 19 through index 1018) contain 88888. + • The next index which produces a triple is 39; the hash of abc39 contains eee. It is also the first key: one of the next thousand hashes (the one at index 816) + contains eeeee. + • None of the next six triples are keys, but the one after that, at index 92, is: it contains 999 and index 200 contains 99999. + • Eventually, index 22728 meets all of the criteria to generate the 64th key. + + So, using our example salt of abc, index 22728 produces the 64th key. + + Given the actual salt in your puzzle input, what index produces your 64th one-time pad key? + + Your puzzle input was cuanljph. + + Your puzzle answer was ________. + +--- Part Two --- + + Of course, in order to make this process even more secure, you've also implemented key stretching. + + Key stretching forces attackers to spend more time generating hashes. Unfortunately, it forces everyone else to spend more time, too. + + To implement key stretching, whenever you generate a hash, before you use it, you first find the MD5 hash of that hash, then the MD5 hash of that hash, and so on, a + total of 2016 additional hashings. Always use lowercase hexadecimal representations of hashes. + + For example, to find the stretched hash for index 0 and salt abc: + + • Find the MD5 hash of abc0: 577571be4de9dcce85a041ba0410f29f. + • Then, find the MD5 hash of that hash: eec80a0c92dc8a0777c619d9bb51e910. + • Then, find the MD5 hash of that hash: 16062ce768787384c81fe17a7a60c7e3. + • ...repeat many times... + • Then, find the MD5 hash of that hash: a107ff634856bb300138cac6568c0f24. + + So, the stretched hash for index 0 in this situation is a107ff.... In the end, you find the original hash (one use of MD5), then find the hash-of-the-previous-hash 2016 + times, for a total of 2017 uses of MD5. + + The rest of the process remains the same, but now the keys are entirely different. Again for salt abc: + + • The first triple (222, at index 5) has no matching 22222 in the next thousand hashes. + • The second triple (eee, at index 10) hash a matching eeeee at index 89, and so it is the first key. + • Eventually, index 22551 produces the 64th key (triple fff with matching fffff at index 22859. + + Given the actual salt in your puzzle input and using 2016 extra MD5 calls of key stretching, what index now produces your 64th one-time pad key? + + Your puzzle answer was ________. + + Your puzzle input was cuanljph. + +References + + Visible links + . http://adventofcode.com/ + . http://adventofcode.com/2016/about + . http://adventofcode.com/2016/support + . http://adventofcode.com/2016/events + . http://adventofcode.com/2016/settings + . http://adventofcode.com/2016/auth/logout + . http://adventofcode.com/2016 + . http://adventofcode.com/2016 + . http://adventofcode.com/2016/leaderboard + . http://adventofcode.com/2016/stats + . http://adventofcode.com/2016/sponsors + . http://adventofcode.com/2016/sponsors + . https://en.wikipedia.org/wiki/One-time_pad + . https://en.wikipedia.org/wiki/Security_through_obscurity + . https://en.wikipedia.org/wiki/MD5 + . https://en.wikipedia.org/wiki/Salt_(cryptography) + . https://en.wikipedia.org/wiki/MD5#Security + . https://en.wikipedia.org/wiki/Key_stretching + . http://adventofcode.com/2016