diff --git a/src/main.cpp b/src/main.cpp index fbf6ab9..4228b0d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,6 +69,7 @@ bool NextCode(std::string& buffer, size_t start) { } // see https://bisqwit.iki.fi/jutut/kuvat/programming_examples/cpp_thread_tutorial/ver05.cc +// this version of the code doesn't even need to worry about synchronization namespace { unsigned ln = 1; @@ -86,15 +87,17 @@ namespace { return "\r" + (m < 0 ? "\33[" + std::to_string(-m) + 'A' : std::string(m, '\n')); } - std::mutex print_lock; - } // namespace -struct BruteThreadState { - BruteThreadState(unsigned line) : line(line) {} +struct ThreadDisplayData { + ThreadDisplayData() { codeString.resize(8); } - void DisplayProgress(const std::string& code, std::uint32_t hash) { - std::lock_guard lk(print_lock); + std::uint32_t threadIndex; + std::string codeString; + std::uint32_t codeHash; + bool done = false; + + void DisplayProgress() { struct FputcIterator { using iterator_category = std::output_iterator_tag; using value_type = void; @@ -116,34 +119,51 @@ struct BruteThreadState { std::FILE* file; }; - std::format_to(FputcIterator(stdout), "{}Thread {:2}: Trying code {}{} {}({:08x}){}", Line(line), line, Color(172), code, Color(166), hash, - Reset()); + if(!done) + std::format_to(FputcIterator(stdout), "{}Thread {:2}: Trying code {}{} {}({:08x}){}", Line(threadIndex), threadIndex, Color(172), + codeString, Color(166), codeHash, Reset()); + else { + std::format_to(FputcIterator(stdout), "{}Thread {:2}: {}Finished!{}", Line(threadIndex), threadIndex, Color(172), Reset()); + } std::fflush(stdout); } +}; + +std::vector data(26); + +struct BruteThreadState { + BruteThreadState(unsigned tid) : threadIndex(tid) {} void BruteForce(char prefix) { // for(std::uint32_t i = 8; i <= code_length; ++i) { - std::string test_buffer(code_length, 'a'); + test_buffer.resize(code_length, 'a'); test_buffer[0] = prefix; // test all possible combinations while(true) { // std::string test_buffer = RandomString(code_length, rng); - auto hash = SwsfScramble(test_buffer); + hash = SwsfScramble(test_buffer); if(hash == code_hash) { std::cerr << std::format("match: {} ({:08x})\n", test_buffer, hash); } - DisplayProgress(test_buffer, hash); + memcpy(data[threadIndex].codeString.data(), test_buffer.data(), test_buffer.length()); + data[threadIndex].codeHash = hash; + + // DisplayProgress(test_buffer, hash); if(!NextCode(test_buffer, 1)) break; } //} + + data[threadIndex].done = true; } - private: - unsigned line; + std::string test_buffer; + std::uint32_t hash; + + unsigned threadIndex; std::random_device rd; // swbf::Xoshiro256ss rng{rd}; }; @@ -151,17 +171,33 @@ struct BruteThreadState { int main() { asio::io_context ioc; - asio::thread_pool pool(26); + asio::thread_pool pool(27); - auto line = 0u; + auto threadIndex = 0u; // post worker threads to run onto the thread pool & wait for them to complete for(int i = 0; i < 26; ++i) - asio::post(pool, [i, l = line++]() { - BruteThreadState state(l); + asio::post(pool, [&, i, tid = threadIndex++]() { + BruteThreadState state(tid); + data[tid].threadIndex = tid; state.BruteForce('a' + i); }); - pool.join(); + bool done = false; + + while(!done) { + int doneIndex = 0; + for(auto& d : data) { + if(d.done) + doneIndex++; + d.DisplayProgress(); + } + + if(doneIndex == 26) { + done = true; + } + } + + pool.join(); // just in case! return 0; }