#include #include #include #include "defs.hpp" const char keyboard[2][4][15] = {{"`1234567890-=", "\0qwertyuiop[]\\", "\0asdfghjkl;'", "\0zxcvbnm,./"}, {"~!@#$%^&*()_+", "\0QWERTYUIOP{}|", "\0ASDFGHJKL:\"", "\0ZXCVBNM<>?"}}; auto string_to_cord(const std::string &password) -> std::vector { std::vector ret; for (auto ch : password) { for (const auto &kbd : keyboard) { for (int j = 0; j < 4; ++j) { auto bgn = kbd[j][0] == '\0' ? 1 : 0; auto pos = std::strchr(kbd[j] + bgn, ch); if (pos) { ret.push_back({j, static_cast(pos - kbd[j])}); break; } } } } return ret; } auto cord_to_string(const std::vector &cords) -> std::string { std::ostringstream ret; for (auto cord : cords) { auto ch = keyboard[0][cord.x][cord.y]; // only consider not shifted keyboard if (ch != '\0') ret << ch; else spdlog::warn("cord_to_string: invalid cord: ({}, {})", cord.x, cord.y); } return ret.str(); } auto is_neighbour(const Cord &a, const Cord &b) -> bool { auto [x1, y1] = a; auto [x2, y2] = b; auto same = x1 == x2 && y1 == y2; // NOTE: consider the case of `same` is true return !same && std::abs(x1 - x2) <= 1 && std::abs(y1 - y2) <= 1; } void stat_keystroke(const DataSource &source) { spdlog::info("stat_keystroke({})", magic_enum::enum_name(source)); std::map stat; for (auto const &password : passwords(source)) { if (password.size() <= 1) continue; auto cords = string_to_cord(password); if (cords.size() <= 1) continue; std::string longest; size_t max_len = 0, cur_len = 1; for (int i = 0; i < cords.size() - 1; i++) { auto ok = is_neighbour(cords[i], cords[i + 1]); if (ok) { cur_len++; } else { if (cur_len > max_len) { max_len = cur_len; longest = cord_to_string( std::vector(cords.begin() + (int)(i - cur_len + 1), cords.begin() + i + 1)); } cur_len = 1; } } if (max_len >= 4) stat[longest]++; } std::vector> vec(stat.begin(), stat.end()); std::sort(vec.begin(), vec.end(), [](auto const &lhs, auto const &rhs) { return lhs.second > rhs.second; }); for (auto const &[length, count] : vec | std::views::take(10)) spdlog::info("{}: {}", length, count); }