#include #include #include #include #include #include #include "defs.hpp" bool is_num(char c) { return c >= '0' && c <= '9'; } bool is_alpha(char c) { return std::isalpha(c); } std::string tolower(const std::string &raw) { auto ret = raw; std::transform(ret.begin(), ret.end(), ret.begin(), [](unsigned char c) { return std::tolower(c); }); return ret; } static std::vector data_buf[2]; enum class BufStatus { INIT, FILLING, DONE }; static BufStatus data_buf_ok[2] = {BufStatus::INIT, BufStatus::INIT}; std::generator passwords(const DataSource &source) { if (data_buf_ok[magic_enum::enum_integer(source)] == BufStatus::DONE) { for (auto const &password : data_buf[magic_enum::enum_integer(source)]) co_yield password; co_return; } if (data_buf_ok[magic_enum::enum_integer(source)] == BufStatus::INIT) data_buf_ok[magic_enum::enum_integer(source)] = BufStatus::FILLING; auto filename = "data/"s + (source == DataSource::CSDN ? "www.csdn.net.sql"s : "plaintxt_yahoo.txt"s); std::ifstream is(filename); if (!is.is_open()) { spdlog::error("failed to open {}", filename); co_return; } switch (source) { case DataSource::CSDN: { constexpr auto delim{" # "sv}; std::string line; while (std::getline(is, line)) { auto segments = line | std::views::split(delim); auto second = *std::ranges::next(segments.begin(), 1); auto password = std::string(second.begin(), second.end()); if (data_buf_ok[magic_enum::enum_integer(source)] == BufStatus::FILLING) data_buf[magic_enum::enum_integer(source)].push_back(password); co_yield password; } } break; case DataSource::YAHOO: { constexpr auto delim{":"sv}; std::string line; while (std::getline(is, line)) { std::erase(line, '\r'); if (line.empty() || !is_num(line[0])) continue; if (is_num(line[0]) && line[1] == '.') continue; auto segments = line | std::views::split(delim); auto third = *std::ranges::next(segments.begin(), 2); auto password = std::string(third.begin(), third.end()); if (password.empty()) continue; if (data_buf_ok[magic_enum::enum_integer(source)] == BufStatus::FILLING) data_buf[magic_enum::enum_integer(source)].push_back(password); co_yield password; } } break; default: std::unreachable(); } data_buf_ok[magic_enum::enum_integer(source)] = BufStatus::DONE; is.close(); co_return; }