summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Base64.h17
-rw-r--r--lib/Base64.cc93
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;
+}