2023-11-03 21:05:08 +08:00
|
|
|
#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) {
|
2023-11-03 21:28:08 +08:00
|
|
|
for (auto const &password : data_buf[magic_enum::enum_integer(source)])
|
2023-11-03 21:05:08 +08:00
|
|
|
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;
|
2023-11-03 21:28:08 +08:00
|
|
|
}
|