| 88 | namespace comm { |
| 89 | |
| 90 | std::string Base64::encode(const std::vector<uint8_t> &data) { |
| 91 | const auto size = data.size(); |
| 92 | const auto remainder = size % 3; |
| 93 | const auto baseLength = size - remainder; |
| 94 | |
| 95 | // three bytes are encoded by 4 base64 chars |
| 96 | std::string encoded; |
| 97 | encoded.reserve(4 * ceil(size / 3)); |
| 98 | |
| 99 | for (std::size_t i = 0; i < baseLength; i += 3) { |
| 100 | const auto b64_chars = encode_triplet(data[i], data[i + 1], data[i + 2]); |
| 101 | std::copy(begin(b64_chars), end(b64_chars), back_inserter(encoded)); |
| 102 | } |
| 103 | |
| 104 | if (remainder == 1) { |
| 105 | const auto b64_chars = encode_triplet(data.back(), 0x00, 0x00); |
| 106 | encoded.push_back(b64_chars[0]); |
| 107 | encoded.push_back(b64_chars[1]); |
| 108 | encoded.append("=="); |
| 109 | } else if (remainder == 2) { |
| 110 | auto it = data.end() - 2; |
| 111 | const auto b64_chars = encode_triplet(*it, *(it + 1), 0x00); |
| 112 | std::copy_n(begin(b64_chars), 3, back_inserter(encoded)); |
| 113 | encoded.push_back('='); |
| 114 | } |
| 115 | return encoded; |
| 116 | } |
| 117 | |
| 118 | std::vector<uint8_t> Base64::decode(const std::string_view base64String) { |
| 119 | if (base64String.size() == 0) { |