diff --git a/render/Base64.cpp b/render/Base64.cpp new file mode 100644 index 0000000..1669b4b --- /dev/null +++ b/render/Base64.cpp @@ -0,0 +1,55 @@ +#include "Base64.h" + +namespace vf { + +std::string base64Encode(const std::vector& bytes) { + static const char* table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + std::string out; + out.reserve((bytes.size() + 2) / 3 * 4); + std::size_t i = 0; + for (; i + 2 < bytes.size(); i += 3) { + uint32_t n = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; + out.push_back(table[(n >> 18) & 63]); + out.push_back(table[(n >> 12) & 63]); + out.push_back(table[(n >> 6) & 63]); + out.push_back(table[n & 63]); + } + if (i < bytes.size()) { + uint32_t n = bytes[i] << 16; + bool two = (i + 1 < bytes.size()); + if (two) n |= bytes[i + 1] << 8; + out.push_back(table[(n >> 18) & 63]); + out.push_back(table[(n >> 12) & 63]); + out.push_back(two ? table[(n >> 6) & 63] : '='); + out.push_back('='); + } + return out; +} + +std::vector base64Decode(const std::string& text) { + auto value = [](char c) -> int { + if (c >= 'A' && c <= 'Z') return c - 'A'; + if (c >= 'a' && c <= 'z') return c - 'a' + 26; + if (c >= '0' && c <= '9') return c - '0' + 52; + if (c == '+') return 62; + if (c == '/') return 63; + return -1; + }; + std::vector out; + int buffer = 0, bits = 0; + for (char c : text) { + if (c == '=') break; + int v = value(c); + if (v < 0) continue; + buffer = (buffer << 6) | v; + bits += 6; + if (bits >= 8) { + bits -= 8; + out.push_back(static_cast((buffer >> bits) & 0xff)); + } + } + return out; +} + +} // namespace vf diff --git a/render/Base64.h b/render/Base64.h new file mode 100644 index 0000000..23796b1 --- /dev/null +++ b/render/Base64.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include +#include + +namespace vf { + +std::string base64Encode(const std::vector& bytes); +std::vector base64Decode(const std::string& text); + +} // namespace vf