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 < AV_BASE64_SIZE(in_size))
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
00105 #undef printf
00106
00107 #define MAX_DATA_SIZE 1024
00108 #define MAX_ENCODED_SIZE 2048
00109
00110 static int test_encode_decode(const uint8_t *data, unsigned int data_size,
00111 const char *encoded_ref)
00112 {
00113 char encoded[MAX_ENCODED_SIZE];
00114 uint8_t data2[MAX_DATA_SIZE];
00115 int data2_size, max_data2_size = MAX_DATA_SIZE;
00116
00117 if (!av_base64_encode(encoded, MAX_ENCODED_SIZE, data, data_size)) {
00118 printf("Failed: cannot encode the input data\n");
00119 return 1;
00120 }
00121 if (encoded_ref && strcmp(encoded, encoded_ref)) {
00122 printf("Failed: encoded string differs from reference\n"
00123 "Encoded:\n%s\nReference:\n%s\n", encoded, encoded_ref);
00124 return 1;
00125 }
00126
00127 if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) < 0) {
00128 printf("Failed: cannot decode the encoded string\n"
00129 "Encoded:\n%s\n", encoded);
00130 return 1;
00131 }
00132 if (memcmp(data2, data, data_size)) {
00133 printf("Failed: encoded/decoded data differs from original data\n");
00134 return 1;
00135 }
00136
00137 printf("Passed!\n");
00138 return 0;
00139 }
00140
00141 int main(void)
00142 {
00143 int i, error_count = 0;
00144 struct test {
00145 const uint8_t *data;
00146 const char *encoded_ref;
00147 } tests[] = {
00148 { "", ""},
00149 { "1", "MQ=="},
00150 { "22", "MjI="},
00151 { "333", "MzMz"},
00152 { "4444", "NDQ0NA=="},
00153 { "55555", "NTU1NTU="},
00154 { "666666", "NjY2NjY2"},
00155 { "abc:def", "YWJjOmRlZg=="},
00156 };
00157
00158 printf("Encoding/decoding tests\n");
00159 for (i = 0; i < FF_ARRAY_ELEMS(tests); i++)
00160 error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref);
00161
00162 return error_count;
00163 }
00164
00165
00166 #endif