#include "encoding.hpp" #include #include #include #include #include namespace connector { std::vector decode_base64(const std::string& value) { static const std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; std::array table{}; table.fill(-1); for (std::size_t index = 0; index < alphabet.size(); ++index) { table[static_cast(alphabet[index])] = static_cast(index); } if (value.size() % 4 != 0) throw std::runtime_error("图片数据格式无效"); std::vector output; output.reserve(value.size() / 4 * 3); int accumulator = 0; int bits = -8; bool padding = false; for (const unsigned char c : value) { if (c == '=') { padding = true; continue; } if (padding || table[c] < 0) throw std::runtime_error("图片数据格式无效"); accumulator = (accumulator << 6) | table[c]; bits += 6; if (bits >= 0) { output.push_back(static_cast((accumulator >> bits) & 0xff)); bits -= 8; } } return output; } namespace { int hex_value(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return -1; } } // namespace std::string url_decode(const std::string& value) { std::string output; output.reserve(value.size()); for (std::size_t index = 0; index < value.size(); ++index) { if (value[index] == '+') { output.push_back(' '); } else if (value[index] == '%' && index + 2 < value.size()) { const int high = hex_value(value[index + 1]); const int low = hex_value(value[index + 2]); if (high < 0 || low < 0) throw std::runtime_error("URL 编码无效"); output.push_back(static_cast((high << 4) | low)); index += 2; } else { output.push_back(value[index]); } } return output; } std::string url_encode(const std::string& value) { std::ostringstream output; output << std::uppercase << std::hex; for (const unsigned char c : value) { if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { output << static_cast(c); } else { output << '%' << std::setw(2) << std::setfill('0') << static_cast(c); } } return output.str(); } std::string html_escape(const std::string& value) { std::string output; output.reserve(value.size()); for (const char c : value) { switch (c) { case '&': output += "&"; break; case '<': output += "<"; break; case '>': output += ">"; break; case '"': output += """; break; case '\'': output += "'"; break; default: output.push_back(c); } } return output; } std::string trim(const std::string& value) { std::size_t start = 0; while (start < value.size() && std::isspace(static_cast(value[start]))) ++start; std::size_t end = value.size(); while (end > start && std::isspace(static_cast(value[end - 1]))) --end; return value.substr(start, end - start); } } // namespace connector