#include #include #include #include /** * \brief * \param my_string * \return */ boost::crc_32_type::value_type getCrc32(const std::string_view my_string) { boost::crc_32_type result; result.process_bytes(my_string.data(), my_string.length()); return result.checksum(); } /** * \brief Un nombre ressort sous la forme d'une chaîne de caractère avec les lettres de l'alphabet. A étant 1 puis B = 2, etc. * En gros, c'est la conversion d'une base 10 vers 26. * \tparam T * \param n * \param array */ template alphabet> void findStringInv(const T n, char *array) { // le nombre de lettre présent dans le nouveau mot : le nombre / 26 donnera le nombre de lettre. const std::size_t iterLoop{ n / alphabet.size() }; for (size_t i = 0; i < iterLoop; ++i) { array[i] = alphabet.back(); } if (n < alphabet.size()) { array[0] = alphabet[n - 1]; return; } /*while (n > 0) { array[i] = alphabet[(--n) % alphabet.size()]; n /= alphabetSize; ++i; }*/ } /** * \brief * \tparam T * \param n * \return */ template constexpr std::size_t maxDigits(T n) { std::size_t numDigit = 1; while (n != 0) { n /= 26; ++numDigit; } return numDigit; } template struct NumberBase26 final { std::array data{}; static constexpr std::uint32_t valMax{ 26 }; const std::array &alphabet{}; static constexpr frozen::unordered_map lut = { { 'A', 0 }, { 'B', 1 }, { 'C', 2 }, { 'D', 3 }, { 'E', 4 }, { 'F', 5 }, { 'G', 6 }, { 'H', 7 }, { 'I', 8 }, { 'J', 9 }, { 'K', 10 }, { 'L', 11 }, { 'M', 12 }, { 'N', 13 }, { 'O', 14 }, { 'P', 15 }, { 'Q', 16 }, { 'R', 17 }, { 'S', 18 }, { 'T', 19 }, { 'U', 20 }, { 'V', 21 }, { 'W', 22 }, { 'X', 23 }, { 'Y', 24 }, { 'Z', 25 }, }; NumberBase26() = delete; explicit NumberBase26(const std::array &_alphabet) : alphabet(_alphabet) { data.fill('A'); } ~NumberBase26() noexcept = default; /** * \brief Cela permet d'incrémenter le nombre. * \return */ NumberBase26 &operator++() { std::uint32_t number{ lut.at(data.back()) + 1 }; // C'est là où se trouve l'incrémentation /* * Tant que la retenue se propage à travers les digit, il faut les mettre à 'A' et * poursuivre jusqu'à rencontrer un caractère != 'Z' */ for (auto iter = data.rbegin(); iter != data.rend(); ++iter) { if (retenue) { number = lut.at(*iter) + 1; } if (number == valMax) { *iter = 'A'; retenue = true; } else { *iter = alphabet[number]; retenue = false; break; } } return *this; } friend std::ostream &operator<<(std::ostream &os, const NumberBase26 &number_base_26) { std::for_each(number_base_26.data.cbegin(), number_base_26.data.cend(), [&](const auto &number) -> void { os << number; }); return os; } private: //! Signifie la présence d'une retenue. bool retenue{ false }; }; int main() { // I love deduction guides :D constexpr std::array cheat_list{ 0xDE4B237Du, 0xB22A28D1u, 0x5A783FAEu, 0xEECCEA2Bu, 0x42AF1E28u, 0x555FC201u, 0x2A845345u, 0xE1EF01EAu, 0x771B83FCu, 0x5BF12848u, 0x44453A17u, 0xFCFF1D08u, 0xB69E8532u, 0x8B828076u, 0xDD6ED9E9u, 0xA290FD8Cu, 0x3484B5A7u, 0x43DB914Eu, 0xDBC0DD65u, 0xD08A30FEu, 0x37BF1B4Eu, 0xB5D40866u, 0xE63B0D99u, 0x675B8945u, 0x4987D5EEu, 0x2E8F84E8u, 0x1A9AA3D6u, 0xE842F3BCu, 0x0D5C6A4Eu, 0x74D4FCB1u, 0xB01D13B8u, 0x66516EBCu, 0x4B137E45u, 0x78520E33u, 0x3A577325u, 0xD4966D59u, 0x5FD1B49Du, 0xA7613F99u, 0x1792D871u, 0xCBC579DFu, 0x4FEDCCFFu, 0x44B34866u, 0x2EF877DBu, 0x2781E797u, 0x2BC1A045u, 0xB2AFE368u, 0xFA8DD45Bu, 0x8DED75BDu, 0x1A5526BCu, 0xA48A770Bu, 0xB07D3B32u, 0x80C1E54Bu, 0x5DAD0087u, 0x7F80B950u, 0x6C0FA650u, 0xF46F2FA4u, 0x70164385u, 0x885D0B50u, 0x151BDCB3u, 0xADFA640Au, 0xE57F96CEu, 0x040CF761u, 0xE1B33EB9u, 0xFEDA77F7u, 0x8CA870DDu, 0x9A629401u, 0xF53EF5A5u, 0xF2AA0C1Du, 0xF36345A8u, 0x8990D5E1u, 0xB7013B1Bu, 0xCAEC94EEu, 0x31F0C3CCu, 0xB3B3E72Au, 0xC25CDBFFu, 0xD5CF4EFFu, 0x680416B1u, 0xCF5FDA18u, 0xF01286E9u, 0xA841CC0Au, 0x31EA09CFu, 0xE958788Au, 0x02C83A7Cu, 0xE49C3ED4u, 0x171BA8CCu, 0x86988DAEu, 0x2BDD2FA1u }; constexpr std::array alphabet{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; // taille = 26 constexpr std::size_t maxCompute = 308915776; constexpr std::size_t maxDig = maxDigits(maxCompute); std::array tmp{}; tmp.fill('\0'); NumberBase26 number_base_26{ alphabet }; for (size_t i = 0; i < maxCompute; ++i, ++number_base_26) { const auto crc = ~(getCrc32(std::string_view{ number_base_26.data.data(), maxDig })); if (std::find(cheat_list.cbegin(), cheat_list.cend(), crc) != cheat_list.cend()) std::cout << number_base_26 << ":0x" << std::hex << crc << '\n'; } return EXIT_SUCCESS; }