diff options
-rw-r--r-- | include/Base64.h | 17 | ||||
-rw-r--r-- | lib/Base64.cc | 93 |
2 files changed, 110 insertions, 0 deletions
diff --git a/include/Base64.h b/include/Base64.h new file mode 100644 index 0000000..122f726 --- /dev/null +++ b/include/Base64.h @@ -0,0 +1,17 @@ +#ifndef __BASE64_H__ +#define __BASE64_H__ + +#include <Exceptions.h> + +class Base64 : public Base { + public: + static String encode(char * data, int len); + static unsigned char * decode(const String & str_in, int * len_out); + + private: + static String encode_block(unsigned char in_tab[3], int len); + static int stri(char); + static int decode_block(char s1, char s2, char s3, char s4, unsigned char * out_tab); +}; + +#endif diff --git a/lib/Base64.cc b/lib/Base64.cc new file mode 100644 index 0000000..062dae4 --- /dev/null +++ b/lib/Base64.cc @@ -0,0 +1,93 @@ +#include <Base64.h> + +static char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +String Base64::encode_block(unsigned char in_tab[3], int len) { + char r[5]; + + r[0] = cb64[in_tab[0] >> 2]; + r[1] = cb64[((in_tab[0] & 3) << 4) | ((in_tab[1] & 240) >> 4)]; + r[2] = len > 1 ? cb64[((in_tab[1] & 15) << 2) | ((in_tab[2] & 192) >> 6)] : '='; + r[3] = len > 2 ? cb64[in_tab[2] & 63] : '='; + r[4] = 0; + + return r; +} + +String Base64::encode(char * data, int stream_size) { + String encoded = ""; + unsigned char in_tab[3]; + int len, i, s_pos; + + s_pos = 0; + + while (stream_size > 0) { + in_tab[0] = 0; + in_tab[1] = 0; + in_tab[2] = 0; + + len = stream_size >= 3 ? 3 : stream_size; + + for (i = 0; i < len; i++) { + in_tab[i] = data[s_pos + i]; + } + + encoded += encode_block(in_tab, len); + + s_pos += 3; + stream_size -= 3; + } + + return encoded; +} + +int Base64::stri(char x) { + char * p = strchr(cb64, x); + return ((x == '=') || (p == 0)) ? -1 : (p - cb64); +} + +int Base64::decode_block(char s1, char s2, char s3, char s4, unsigned char * out_tab) { + int len, sb1, sb2, sb3, sb4; + + len = s3 == '=' ? 1 : s4 == '=' ? 2 : 3; + s3 = (s3 == '=') || (s3 == 0) ? 'A' : s3; + s4 = (s4 == '=') || (s4 == 0) ? 'A' : s4; + + sb1 = stri(s1); + sb2 = stri(s2); + sb3 = stri(s3); + sb4 = stri(s4); + + out_tab[0] = (sb1 << 2) | (sb2 >> 4); + out_tab[1] = ((sb2 << 4) & 255) | (sb3 >> 2); + out_tab[2] = ((sb3 << 6) & 240) | sb4; + + return len; +} + +unsigned char * Base64::decode(const String & str_in, int * len_out) { + int s_len = str_in.strlen() / 4, len = 0, i, j, t_len; + char s1, s2, s3, s4; + unsigned char t_out[2]; + unsigned char * out = (unsigned char *) malloc(s_len * 3); + + for (i = 0; i < s_len; i++) { + s1 = str_in[i * 4 + 0]; + s2 = str_in[i * 4 + 1]; + s3 = str_in[i * 4 + 2]; + s4 = str_in[i * 4 + 3]; + t_len = decode_block(s1, s2, s3, s4, t_out); + + for (j = 0; j < t_len; j++) { + out[i * 3 + j] = t_out[j]; + } + + len += t_len; + } + + if (len_out) { + *len_out = len; + } + + return out; +} |