// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm // Public domain implementation from https://stackoverflow.com/a/13935718/463796 #include "base64.hpp" #include namespace VideoStitch { namespace Util { typedef unsigned char BYTE; static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; static inline bool is_base64(BYTE c) { return (isalnum(c) || (c == '+') || (c == '/')); } std::string base64_encode(BYTE const* buf, size_t bufLen) { std::string ret; int i = 0; int j = 0; BYTE char_array_3[3]; BYTE char_array_4[4]; while (bufLen--) { char_array_3[i++] = *(buf++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = (BYTE)((char_array_3[0] & 0x03) << 4) + (BYTE)((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = (BYTE)((char_array_3[1] & 0x0f) << 2) + (BYTE)((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (i = 0; (i < 4); i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for (j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = (BYTE)((char_array_3[0] & 0x03) << 4) + (BYTE)((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = (BYTE)((char_array_3[1] & 0x0f) << 2) + (BYTE)((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while ((i++ < 3)) ret += '='; } return ret; } std::vector base64_decode(std::string const& encoded_string) { auto in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; BYTE char_array_4[4], char_array_3[3]; std::vector ret; while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; if (i == 4) { for (i = 0; i < 4; i++) char_array_4[i] = (BYTE)base64_chars.find(char_array_4[i]); char_array_3[0] = (BYTE)(char_array_4[0] << 2) + (BYTE)((char_array_4[1] & 0x30) >> 4); char_array_3[1] = (BYTE)((char_array_4[1] & 0xf) << 4) + (BYTE)((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = (BYTE)((char_array_4[2] & 0x3) << 6) + (BYTE)char_array_4[3]; for (i = 0; (i < 3); i++) ret.push_back(char_array_3[i]); i = 0; } } if (i) { for (j = i; j < 4; j++) char_array_4[j] = 0; for (j = 0; j < 4; j++) char_array_4[j] = (BYTE)base64_chars.find(char_array_4[j]); char_array_3[0] = (BYTE)(char_array_4[0] << 2) + (BYTE)((char_array_4[1] & 0x30) >> 4); char_array_3[1] = (BYTE)((char_array_4[1] & 0xf) << 4) + (BYTE)((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = (BYTE)((char_array_4[2] & 0x3) << 6) + (BYTE)char_array_4[3]; for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); } return ret; } std::string base64Encode(const std::string& input) { return base64_encode((unsigned char*)input.data(), input.size()); } std::string base64Decode(const std::string& str64) { std::vector data = base64_decode(str64); return std::string((char*)data.data(), data.size()); } } // namespace Util } // namespace VideoStitch