00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #include "common.h"
00028 #include "base64.h"
00029
00030
00031 static const uint8_t map2[] =
00032 {
00033 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36,
00034 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff,
00035 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01,
00036 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
00037 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
00038 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
00039 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b,
00040 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
00041 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
00042 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
00043 };
00044
00045 int av_base64_decode(uint8_t *out, const char *in, int out_size)
00046 {
00047 int i, v;
00048 uint8_t *dst = out;
00049
00050 v = 0;
00051 for (i = 0; in[i] && in[i] != '='; i++) {
00052 unsigned int index= in[i]-43;
00053 if (index>=FF_ARRAY_ELEMS(map2) || map2[index] == 0xff)
00054 return -1;
00055 v = (v << 6) + map2[index];
00056 if (i & 3) {
00057 if (dst - out < out_size) {
00058 *dst++ = v >> (6 - 2 * (i & 3));
00059 }
00060 }
00061 }
00062
00063 return dst - out;
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 char *av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
00073 {
00074 static const char b64[] =
00075 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00076 char *ret, *dst;
00077 unsigned i_bits = 0;
00078 int i_shift = 0;
00079 int bytes_remaining = in_size;
00080
00081 if (in_size >= UINT_MAX / 4 ||
00082 out_size < (in_size+2) / 3 * 4 + 1)
00083 return NULL;
00084 ret = dst = out;
00085 while (bytes_remaining) {
00086 i_bits = (i_bits << 8) + *in++;
00087 bytes_remaining--;
00088 i_shift += 8;
00089
00090 do {
00091 *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f];
00092 i_shift -= 6;
00093 } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0));
00094 }
00095 while ((dst - ret) & 3)
00096 *dst++ = '=';
00097 *dst = '\0';
00098
00099 return ret;
00100 }
00101
00102 #ifdef TEST
00103
00104 #undef printf
00105
00106 #define MAX_DATA_SIZE 1024
00107 #define MAX_ENCODED_SIZE 2048
00108
00109 int test_encode_decode(const uint8_t *data, unsigned int data_size, const char *encoded_ref)
00110 {
00111 char encoded[MAX_ENCODED_SIZE];
00112 uint8_t data2[MAX_DATA_SIZE];
00113 int data2_size, max_data2_size = MAX_DATA_SIZE;
00114
00115 if (!av_base64_encode(encoded, MAX_ENCODED_SIZE, data, data_size)) {
00116 printf("Failed: cannot encode the input data\n");
00117 return 1;
00118 }
00119 if (encoded_ref && strcmp(encoded, encoded_ref)) {
00120 printf("Failed: encoded string differs from reference\n"
00121 "Encoded:\n%s\nReference:\n%s\n", encoded, encoded_ref);
00122 return 1;
00123 }
00124
00125 if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) < 0) {
00126 printf("Failed: cannot decode the encoded string\n"
00127 "Encoded:\n%s\n", encoded);
00128 return 1;
00129 }
00130 if (memcmp(data2, data, data_size)) {
00131 printf("Failed: encoded/decoded data differs from original data\n");
00132 return 1;
00133 }
00134
00135 printf("Passed!\n");
00136 return 0;
00137 }
00138
00139 int main(void)
00140 {
00141 int i, error_count = 0;
00142 struct test {
00143 const uint8_t *data;
00144 const char *encoded_ref;
00145 } tests[] = {
00146 { "", ""},
00147 { "1", "MQ=="},
00148 { "22", "MjI="},
00149 { "333", "MzMz"},
00150 { "4444", "NDQ0NA=="},
00151 { "55555", "NTU1NTU="},
00152 { "666666", "NjY2NjY2"},
00153 { "abc:def", "YWJjOmRlZg=="},
00154 };
00155
00156 printf("Encoding/decoding tests\n");
00157 for (i = 0; i < FF_ARRAY_ELEMS(tests); i++)
00158 error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref);
00159
00160 return error_count;
00161 }
00162
00163 #endif