#pragma once // base36_codec.hpp #ifndef BASE36_CODEC_HPP #define BASE36_CODEC_HPP #include #include #include #include //By ChatGPT: 1:1 converted from base36 library source code namespace basecodec { // Base36 alphabet inline constexpr const char* base36_alphabet = "0123456789abcdefghijklmnopqrstuvwxyz"; // Python: line 17 // def dumps(number): inline bool encodeBase36(int64_t number, std::string& result) noexcept { result.clear(); // Python: line 23 if (number < 0) { std::string positive; if (!encodeBase36(-number, positive)) return false; result = '-' + positive; return true; } // Python: line 26 if (number == 0) { result = "0"; return true; } std::string value; while (number != 0) { int remainder = number % 36; number /= 36; value.insert(value.begin(), base36_alphabet[remainder]); } result = std::move(value); return true; } inline bool encodeBase36FromDecimalString(const std::string& decimalStr, std::string& base36Out) noexcept { uint64_t number = 0; auto [ptr, ec] = std::from_chars(decimalStr.data(), decimalStr.data() + decimalStr.size(), number, 10); if (ec != std::errc()) return false; static const char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz"; std::string result; do { result.insert(result.begin(), alphabet[number % 36]); number /= 36; } while (number != 0); base36Out = result; return true; } // Python: line 35 // def loads(value): inline bool decodeBase36(const std::string& input, int64_t& number) noexcept { // Validate input: allow optional leading '-', rest must be base36 chars size_t start = 0; bool negative = false; if (!input.empty() && input[0] == '-') { negative = true; start = 1; } if (start == input.size()) return false; // "-" alone is invalid number = 0; for (size_t i = start; i < input.size(); ++i) { char c = std::tolower(input[i]); int digit; if (c >= '0' && c <= '9') digit = c - '0'; else if (c >= 'a' && c <= 'z') digit = c - 'a' + 10; else return false; // invalid character #pragma push_macro("max") #undef max if (number > (std::numeric_limits::max() - digit) / 36) return false; // overflow #pragma pop_macro("max") number = number * 36 + digit; } if (negative) number = -number; return true; } inline bool decodeBase36ToDecimalString(const std::string& base36Str, std::string& decimalOut) noexcept { uint64_t number = 0; for (char c : base36Str) { int digit = 0; if (c >= '0' && c <= '9') digit = c - '0'; else if (c >= 'a' && c <= 'z') digit = c - 'a' + 10; else if (c >= 'A' && c <= 'Z') digit = c - 'A' + 10; // case-insensitive else return false; // invalid character if (digit >= 36) return false; number = number * 36 + digit; } // Convert number to string using std::to_string decimalOut = std::to_string(number); return true; } } // namespace basecodec #endif // BASE36_CODEC_HPP