#include #include #include #include #include #include using namespace boost::algorithm; bool isValid(const std::string &ibanstring) { static std::map countrycodes { {"AL", 28}, {"AD", 24}, {"AT", 20}, {"AZ", 28 }, {"BE", 16}, {"BH", 22}, {"BA", 20}, {"BR", 29 }, {"BG", 22}, {"CR", 21}, {"HR", 21}, {"CY", 28 }, {"CZ", 24}, {"DK", 18}, {"DO", 28}, {"EE", 20 }, {"FO", 18}, {"FI", 18}, {"FR", 27}, {"GE", 22 }, {"DE", 22}, {"GI", 23}, {"GR", 27}, {"GL", 18 }, {"GT", 28}, {"HU", 28}, {"IS", 26}, {"IE", 22 }, {"IL", 23}, {"IT", 27}, {"KZ", 20}, {"KW", 30 }, {"LV", 21}, {"LB", 28}, {"LI", 21}, {"LT", 20 }, {"LU", 20}, {"MK", 19}, {"MT", 31}, {"MR", 27 }, {"MU", 30}, {"MC", 27}, {"MD", 24}, {"ME", 22 }, {"NL", 18}, {"NO", 15}, {"PK", 24}, {"PS", 29 }, {"PL", 28}, {"PT", 25}, {"RO", 24}, {"SM", 27 }, {"SA", 24}, {"RS", 22}, {"SK", 24}, {"SI", 19 }, {"ES", 24}, {"SE", 24}, {"CH", 21}, {"TN", 24 }, {"TR", 26}, {"AE", 23}, {"GB", 22}, {"VG", 24 } }; std::string teststring(ibanstring); erase_all(teststring, " "); //defined in boost/algorithm/string.hpp if (countrycodes.find(teststring.substr(0, 2)) == countrycodes.end()) return false; if (teststring.length() != countrycodes[teststring.substr(0, 2)]) return false; if (!all(teststring, is_alnum())) return false; to_upper(teststring); std::rotate(teststring.begin(), teststring.begin() + 4, teststring.end()); std::string numberstring; // will contain the letter substitutions for (const auto &c : teststring) { if (std::isdigit(c)) numberstring += c; if (std::isupper(c)) numberstring += std::to_string(static_cast(c) - 55); } // implements a stepwise check for mod 97 in chunks of 9 at the first time, // then in chunks of seven prepended by the last mod 97 operation converted // to a string int segstart = 0; int step = 9; std::string prepended; long number = 0; while (segstart < numberstring.length() - step) { number = std::stol(prepended + numberstring.substr(segstart, step)); int remainder = number % 97; prepended = std::to_string(remainder); if (remainder < 10) prepended = "0" + prepended; segstart = segstart + step; step = 7; } number = std::stol(prepended + numberstring.substr(segstart)); return (number % 97 == 1); } void SayValidity(const std::string &iban) { std::cout << iban << (isValid(iban) ? " is " : " is not ") << "valid\n"; } int main() { SayValidity("GB82 WEST 1234 5698 7654 32"); SayValidity("GB82TEST12345698765432"); return 0; }