62 lines
2.1 KiB
C++
62 lines
2.1 KiB
C++
#include "base64.h"
|
|
#include <iostream>
|
|
#include <cctype>
|
|
|
|
std::string base64_decode(const std::string& encoded) {
|
|
const std::string base64_chars =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
"abcdefghijklmnopqrstuvwxyz"
|
|
"0123456789+/";
|
|
|
|
size_t in_len = encoded.size();
|
|
size_t i = 0;
|
|
size_t in_ = 0;
|
|
unsigned char char_array_4[4], char_array_3[3];
|
|
std::string decoded;
|
|
|
|
while (in_ < in_len && encoded[in_] != '=' &&
|
|
(std::isalnum(encoded[in_]) || encoded[in_] == '+' || encoded[in_] == '/')) {
|
|
char_array_4[i++] = encoded[in_++];
|
|
if (i == 4) {
|
|
// Translate values in char_array_4 from base64 alphabet to indices
|
|
for (i = 0; i < 4; i++) {
|
|
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
|
}
|
|
|
|
// Decode to original bytes
|
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
decoded += char_array_3[i];
|
|
}
|
|
i = 0;
|
|
}
|
|
}
|
|
|
|
// Handle any remaining bytes
|
|
if (i) {
|
|
// Fill remaining positions with zeros
|
|
for (size_t j = i; j < 4; j++) {
|
|
char_array_4[j] = 0;
|
|
}
|
|
|
|
// Convert to indices
|
|
for (size_t j = 0; j < 4; j++) {
|
|
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
|
}
|
|
|
|
// Decode remaining bytes
|
|
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
|
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
|
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
|
|
|
// Only add valid bytes based on how many characters we had
|
|
for (size_t j = 0; j < i - 1; j++) {
|
|
decoded += char_array_3[j];
|
|
}
|
|
}
|
|
|
|
return decoded;
|
|
}
|