From 4ba7f6bf14c2d98512996967d2c747f0733b7e83 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Fri, 3 Dec 2021 17:13:37 +0000 Subject: [PATCH] Add 2016 Day 5 puzzles --- 2016/puzzle-05-01.CMakeLists.txt | 2 ++ 2016/puzzle-05-01.cc | 59 ++++++++++++++++++++++++++++++++ 2016/puzzle-05-02.CMakeLists.txt | 2 ++ 2016/puzzle-05-02.cc | 56 ++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 2016/puzzle-05-01.CMakeLists.txt create mode 100644 2016/puzzle-05-01.cc create mode 100644 2016/puzzle-05-02.CMakeLists.txt create mode 100644 2016/puzzle-05-02.cc diff --git a/2016/puzzle-05-01.CMakeLists.txt b/2016/puzzle-05-01.CMakeLists.txt new file mode 100644 index 0000000..1f298ff --- /dev/null +++ b/2016/puzzle-05-01.CMakeLists.txt @@ -0,0 +1,2 @@ +find_package(OpenSSL REQUIRED) +target_link_libraries("${puzzle_name}" OpenSSL::SSL) diff --git a/2016/puzzle-05-01.cc b/2016/puzzle-05-01.cc new file mode 100644 index 0000000..b9d66bc --- /dev/null +++ b/2016/puzzle-05-01.cc @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +#include + +using MD5Digest = std::array; + +auto md5(MD5Digest& digest, std::string const& s) -> unsigned int +{ + EVP_MD const* md{EVP_md5()}; + unsigned int md_len{0}; + + EVP_MD_CTX* md_context{EVP_MD_CTX_new()}; + assert(md_context != nullptr); + EVP_DigestInit_ex2(md_context, md, nullptr); + EVP_DigestUpdate(md_context, s.data(), s.length()); + EVP_DigestFinal_ex(md_context, digest.data(), &md_len); + return md_len; +} + +auto get_letter(std::string const& s) -> unsigned +{ + MD5Digest digest; + auto len = md5(digest, s); + assert(len >= 3); + if (digest[0] == 0 && digest[1] == 0 && (digest[2] & 0xf0) == 0) { + return digest[2] & 0xf; + } + return 16; +} + +auto main() -> int +{ + constexpr std::string_view characters{"0123456789abcdef"}; + constexpr unsigned password_length{8}; + + std::string result; + std::string line; + if (!std::getline(std::cin, line)) { + std::cerr << "Unable to read from stdin.\n"; + return 1; + } + + std::uint64_t i{0}; + for (unsigned letter = 0; letter < password_length; ++letter) { + unsigned c{0}; + while ((c = get_letter(line + std::to_string(i))) == 16) { + ++i; + } + result += characters.at(c); + ++i; + } + + std::cout << "Password: " << result << '\n'; + return 0; +} \ No newline at end of file diff --git a/2016/puzzle-05-02.CMakeLists.txt b/2016/puzzle-05-02.CMakeLists.txt new file mode 100644 index 0000000..1f298ff --- /dev/null +++ b/2016/puzzle-05-02.CMakeLists.txt @@ -0,0 +1,2 @@ +find_package(OpenSSL REQUIRED) +target_link_libraries("${puzzle_name}" OpenSSL::SSL) diff --git a/2016/puzzle-05-02.cc b/2016/puzzle-05-02.cc new file mode 100644 index 0000000..374dc5c --- /dev/null +++ b/2016/puzzle-05-02.cc @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +#include + +using MD5Digest = std::array; + +auto md5(MD5Digest& digest, std::string const& s) -> unsigned int +{ + EVP_MD const* md{EVP_md5()}; + unsigned int md_len{0}; + + EVP_MD_CTX* md_context{EVP_MD_CTX_new()}; + assert(md_context != nullptr); + EVP_DigestInit_ex2(md_context, md, nullptr); + EVP_DigestUpdate(md_context, s.data(), s.length()); + EVP_DigestFinal_ex(md_context, digest.data(), &md_len); + return md_len; +} + +auto main() -> int +{ + constexpr std::string_view characters{"0123456789abcdef"}; + constexpr unsigned password_length{8}; + + std::string result{"--------"}; + std::string line; + if (!std::getline(std::cin, line)) { + std::cerr << "Unable to read from stdin.\n"; + return 1; + } + + std::uint64_t i{0}; + while (std::any_of(result.begin(), result.end(), [](char c) { return c == '-'; })) { + MD5Digest digest; + auto len = md5(digest, line + std::to_string(i)); + assert(len >= 3); + if (digest[0] == 0 && digest[1] == 0 && (digest[2] & 0xf0) == 0) { + auto idx{digest[2] & 0xf}; + if (idx < password_length) { + if (result.at(idx) == '-') { + result[idx] = characters[(digest[3] & 0xf0) >> 4]; + std::cout << '\n'; + } + } + } + std::cout << '\r' << result << ' ' << line << i << std::flush; + ++i; + } + + std::cout << "\nPassword: " << result << '\n'; + return 0; +} \ No newline at end of file