Created
January 6, 2021 03:11
-
-
Save eklitzke/3b70e2ebefb81c5fee234347a18856ba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
std::string DecodeBase64(std::string_view input) { | |
static const uint8_t b64_decode[] = { | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, | |
64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, | |
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, | |
23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, | |
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}; | |
size_t in_len = input.size(); | |
ASSERT_DEBUG(in_len % 4 == 0); | |
size_t out_len = in_len / 4 * 3; | |
if (input[in_len - 1] == '=') out_len--; | |
if (input[in_len - 2] == '=') out_len--; | |
std::string out(out_len, 0); | |
for (size_t i = 0, j = 0; i < in_len;) { | |
uint32_t a = input[i] == '=' ? 0 & i++ : b64_decode[static_cast<int>(input[i++])]; | |
uint32_t b = input[i] == '=' ? 0 & i++ : b64_decode[static_cast<int>(input[i++])]; | |
uint32_t c = input[i] == '=' ? 0 & i++ : b64_decode[static_cast<int>(input[i++])]; | |
uint32_t d = input[i] == '=' ? 0 & i++ : b64_decode[static_cast<int>(input[i++])]; | |
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6); | |
if (j < out_len) out[j++] = (triple >> 2 * 8) & 0xFF; | |
if (j < out_len) out[j++] = (triple >> 1 * 8) & 0xFF; | |
if (j < out_len) out[j++] = (triple >> 0 * 8) & 0xFF; | |
} | |
return out; | |
} | |
std::string EncodeBase64(std::string_view v) { | |
size_t sz = v.size(); | |
size_t padding = sz % 3; | |
if (padding) { | |
padding = 3 - padding; | |
} | |
sz += padding; | |
ASSERT_DEBUG(sz % 3 == 0); | |
std::string out(sz * 4 / 3, 0); | |
// base64 lookup table | |
static const char b64_encode[] = | |
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
size_t p = 0; | |
for (size_t i = 0; i < sz; i += 3) { | |
uint8_t b = v[i] >> 2; | |
ASSERT_DEBUG(b < 64); | |
out[p++] = b64_encode[b]; | |
b = ((v[i] & 0x3) << 4) + (v[i + 1] >> 4); | |
ASSERT_DEBUG(b < 64); | |
out[p++] = b64_encode[b]; | |
b = ((v[i + 1] & 0xf) << 2) + (v[i + 2] >> 6); | |
ASSERT_DEBUG(b < 64); | |
out[p++] = b64_encode[b]; | |
b = v[i + 2] & 0x3f; | |
ASSERT_DEBUG(b < 64); | |
out[p++] = b64_encode[b]; | |
} | |
// add padding bytes | |
for (size_t i = 0; i < padding; i++) { | |
out[p++] = '='; | |
} | |
ASSERT_DEBUG(p == out.size()); | |
return out; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment