password-analyzer/utils.cpp
2023-11-03 21:05:08 +08:00

76 lines
2.6 KiB
C++

#include <cctype>
#include <fstream>
#include <ranges>
#include <string>
#include <utility>
#include "defs.hpp"
bool is_num(char c) { return c >= '0' && c <= '9'; }
bool is_alpha(char c) { return std::isalpha(c); }
static std::vector<std::string> data_buf[2];
enum class BufStatus { INIT, FILLING, DONE };
static BufStatus data_buf_ok[2] = {BufStatus::INIT, BufStatus::INIT};
std::generator<std::string> 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;
}