104 lines
2.5 KiB
C++
104 lines
2.5 KiB
C++
#include "ehs/Base64.h"
|
|
|
|
namespace ehs
|
|
{
|
|
const char Base64::ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
Str_8 Base64::Encode(const Str_8 &input)
|
|
{
|
|
UInt_64 input_length = input.Size();
|
|
|
|
// Calculate the output length
|
|
UInt_64 output_length = 4 * ((input_length + 2) / 3);
|
|
|
|
// Allocate memory for the output
|
|
Str_8 result(output_length);
|
|
|
|
// Loop through the input and fill the output
|
|
for (int i = 0, j = 0; i < input_length;) {
|
|
|
|
// Take first byte and shift right by 2 bits
|
|
UInt_32 octet_a = i < input_length ? input[i++] : 0;
|
|
UInt_32 octet_b = i < input_length ? input[i++] : 0;
|
|
UInt_32 octet_c = i < input_length ? input[i++] : 0;
|
|
|
|
UInt_32 triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
|
|
|
// Encode the 24-bits into four 6-bits integers
|
|
result[j++] = ascii[(triple >> 3 * 6) & 0x3F];
|
|
result[j++] = ascii[(triple >> 2 * 6) & 0x3F];
|
|
result[j++] = ascii[(triple >> 1 * 6) & 0x3F];
|
|
result[j++] = ascii[(triple >> 0 * 6) & 0x3F];
|
|
}
|
|
|
|
// Add padding '='
|
|
if (input_length % 3 == 1) {
|
|
result[output_length - 1] = '=';
|
|
result[output_length - 2] = '=';
|
|
} else if (input_length % 3 == 2) {
|
|
result[output_length - 1] = '=';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
Str_8 Base64::Decode(const Str_8 &input)
|
|
{
|
|
UInt_64 in_len = input.Size();
|
|
int i = 0;
|
|
int j = 0;
|
|
int in_ = 0;
|
|
char char_array_4[4], char_array_3[3];
|
|
Str_8 ret;
|
|
|
|
while (in_len-- && ( input[in_] != '=') && IsBase64(input[in_]))
|
|
{
|
|
char_array_4[i++] = input[in_]; in_++;
|
|
|
|
if (i ==4)
|
|
{
|
|
for (i = 0; i <4; i++)
|
|
char_array_4[i] = Find(char_array_4[i]);
|
|
|
|
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++)
|
|
ret += char_array_3[i];
|
|
|
|
i = 0;
|
|
}
|
|
}
|
|
|
|
if (i)
|
|
{
|
|
for (j = 0; j < i; j++)
|
|
char_array_4[j] = Find(char_array_4[j]);
|
|
|
|
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);
|
|
|
|
for (j = 0; (j < i - 1); j++)
|
|
ret += char_array_3[j];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
char Base64::Find(const char c)
|
|
{
|
|
for (char i = 0; i < (char)sizeof(ascii); ++i)
|
|
{
|
|
if (ascii[i] == c)
|
|
return i;
|
|
}
|
|
|
|
return EHS_SINT_8_MAX;
|
|
}
|
|
|
|
bool Base64::IsBase64(const char c)
|
|
{
|
|
return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || (c == '+') || (c == '/');
|
|
}
|
|
} |