#include #include #include #include #include "base64.h" static const char encoding_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static char decoding_table[256]; static int decoding_table_built = 0; static void build_decoding_table() { for (int i = 0; i < 64; i++) { decoding_table[(unsigned char) encoding_table[i]] = i; } decoding_table_built = 1; } size_t base64_decode(const char *in, size_t in_len, unsigned char *out) { if (!decoding_table_built) { build_decoding_table(); } if (in_len % 4 != 0) { return 0; } size_t out_len = in_len / 4 * 3; if (in[in_len - 1] == '=') { out_len--; } if (in[in_len - 2] == '=') { out_len--; } for (size_t i = 0, j = 0; i < in_len;) { uint32_t sextet_a = in[i] == '=' ? 0 : decoding_table[(unsigned char)in[i]]; i++; uint32_t sextet_b = in[i] == '=' ? 0 : decoding_table[(unsigned char)in[i]]; i++; uint32_t sextet_c = in[i] == '=' ? 0 : decoding_table[(unsigned char)in[i]]; i++; uint32_t sextet_d = in[i] == '=' ? 0 : decoding_table[(unsigned char)in[i]]; i++; uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d; if (j < out_len) { out[j++] = (triple >> 16) & 0xFF; } if (j < out_len) { out[j++] = (triple >> 8) & 0xFF; } if (j < out_len) { out[j++] = triple & 0xFF; } } return out_len; }