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