83 lines
1.6 KiB
Go
83 lines
1.6 KiB
Go
|
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 <salt> <key-num>")
|
||
|
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)
|
||
|
}
|