Last active
August 28, 2023 17:44
-
-
Save darelf/0f96e1d313e1d0da5051e1a6eff8d329 to your computer and use it in GitHub Desktop.
Base64 url encode/decode. C++ adapted from some old code by someone else...
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
#include <string> | |
#include <vector> | |
/* | |
Base64 translates 24 bits into 4 ASCII characters at a time. First, | |
3 8-bit bytes are treated as 4 6-bit groups. Those 4 groups are | |
translated into ASCII characters. That is, each 6-bit number is treated | |
as an index into the ASCII character array. | |
If the final set of bits is less 8 or 16 instead of 24, traditional base64 | |
would add a padding character. However, if the length of the data is | |
known, then padding can be eliminated. | |
One difference between the "standard" Base64 is two characters are different. | |
See RFC 4648 for details. | |
This is how we end up with the Base64 URL encoding. | |
*/ | |
const char base64_url_alphabet[] = { | |
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', | |
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', | |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | |
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' | |
}; | |
std::string base64_encode(const std::string & in) { | |
std::string out; | |
int val =0, valb=-6; | |
size_t len = in.length(); | |
unsigned int i = 0; | |
for (i = 0; i < len; i++) { | |
unsigned char c = in[i]; | |
val = (val<<8) + c; | |
valb += 8; | |
while (valb >= 0) { | |
out.push_back(base64_url_alphabet[(val>>valb)&0x3F]); | |
valb -= 6; | |
} | |
} | |
if (valb > -6) { | |
out.push_back(base64_url_alphabet[((val<<8)>>(valb+8))&0x3F]); | |
} | |
return out; | |
} | |
std::string base64_decode(const std::string & in) { | |
std::string out; | |
std::vector<int> T(256, -1); | |
unsigned int i; | |
for (i =0; i < 64; i++) T[base64_url_alphabet[i]] = i; | |
int val = 0, valb = -8; | |
for (i = 0; i < in.length(); i++) { | |
unsigned char c = in[i]; | |
if (T[c] == -1) break; | |
val = (val<<6) + T[c]; | |
valb += 6; | |
if (valb >= 0) { | |
out.push_back(char((val>>valb)&0xFF)); | |
valb -= 8; | |
} | |
} | |
return out; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much for this code, It worked great for my minimal implementation of JSON Web Token, I made a few adjustments after running SonarCloud static analyzer. Since I need to encode string_views and also vector I used a template, and also incorporated std::range:for_each and lambdas to modernize the loops (suggested by SonarCloud):