#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 == '/'); } }