The Ethernet-Board

Dependencies:   EthernetInterface HTTPClient MODSERIAL mbed-dev mbed-rtos wolfSSL

Fork of sose2016_tr_oauth_pop by niko gillen

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers base64.cpp Source File

base64.cpp

00001 #include <stdint.h>
00002 #include <stdlib.h>
00003 
00004 
00005 static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
00006                                 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
00007                                 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
00008                                 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
00009                                 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
00010                                 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
00011                                 'w', 'x', 'y', 'z', '0', '1', '2', '3',
00012                                 '4', '5', '6', '7', '8', '9', '-', '_'};
00013 static char *decoding_table = NULL;
00014 static int mod_table[] = {0, 2, 1};
00015 
00016 
00017 void build_decoding_table() {
00018 
00019     decoding_table = (char*) malloc(256);
00020 
00021     for (int i = 0; i < 64; i++)
00022         decoding_table[(unsigned char) encoding_table[i]] = i;
00023 }
00024 
00025 
00026 void base64_cleanup() {
00027     free(decoding_table);
00028 }
00029 
00030 char *base64_encode(const unsigned char *data,
00031                     size_t input_length,
00032                     size_t *output_length) {
00033 
00034     *output_length = 4 * ((input_length +2) / 3);
00035 
00036     char *encoded_data = (char*) malloc(*output_length);
00037     if (encoded_data == NULL) return NULL;
00038 
00039     for (int i = 0, j = 0; i < input_length;) {
00040 
00041         uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
00042         uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
00043         uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
00044 
00045         uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
00046 
00047         encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
00048         encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
00049         encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
00050         encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
00051     }
00052 
00053     for (int i = 0; i < mod_table[input_length % 3]; i++)
00054         encoded_data[*output_length - 1 - i] = 0x00;
00055 
00056     return encoded_data;
00057 }
00058 
00059 
00060 unsigned char *base64_decode(const char *data,
00061                              size_t input_length,
00062                              size_t *output_length) {
00063 
00064     if (decoding_table == NULL) build_decoding_table();
00065 
00066     if (input_length % 4 != 0) return NULL;
00067 
00068     *output_length = input_length / 4 * 3;
00069     if (data[input_length - 1] == '=') (*output_length)--;
00070     if (data[input_length - 2] == '=') (*output_length)--;
00071 
00072     unsigned char *decoded_data = (unsigned char*) malloc(*output_length);
00073     if (decoded_data == NULL) return NULL;
00074 
00075     for (int i = 0, j = 0; i < input_length;) {
00076 
00077         uint32_t sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
00078         uint32_t sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
00079         uint32_t sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
00080         uint32_t sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[data[i++]];
00081 
00082         uint32_t triple = (sextet_a << 3 * 6)
00083         + (sextet_b << 2 * 6)
00084         + (sextet_c << 1 * 6)
00085         + (sextet_d << 0 * 6);
00086 
00087         if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
00088         if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
00089         if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
00090     }
00091 
00092     return decoded_data;
00093 }