00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #include "common.h"
00029 #include "base64.h"
00030
00031
00032 static const uint8_t map2[] =
00033 {
00034 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36,
00035 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff,
00036 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01,
00037 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
00038 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
00039 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
00040 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b,
00041 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
00042 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
00043 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
00044 };
00045
00046 int av_base64_decode(uint8_t * out, const char *in, int out_length)
00047 {
00048 int i, v;
00049 uint8_t *dst = out;
00050
00051 v = 0;
00052 for (i = 0; in[i] && in[i] != '='; i++) {
00053 unsigned int index= in[i]-43;
00054 if (index>=(sizeof(map2)/sizeof(map2[0])) || map2[index] == 0xff)
00055 return -1;
00056 v = (v << 6) + map2[index];
00057 if (i & 3) {
00058 if (dst - out < out_length) {
00059 *dst++ = v >> (6 - 2 * (i & 3));
00060 }
00061 }
00062 }
00063
00064 return (dst - out);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073 char *av_base64_encode(char * buf, int buf_len, const uint8_t * src, int len)
00074 {
00075 static const char b64[] =
00076 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00077 char *ret, *dst;
00078 unsigned i_bits = 0;
00079 int i_shift = 0;
00080 int bytes_remaining = len;
00081
00082 if (len >= UINT_MAX / 4 ||
00083 buf_len < len * 4 / 3 + 12)
00084 return NULL;
00085 ret = dst = buf;
00086 while (bytes_remaining) {
00087 i_bits = (i_bits << 8) + *src++;
00088 bytes_remaining--;
00089 i_shift += 8;
00090
00091 do {
00092 *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f];
00093 i_shift -= 6;
00094 } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0));
00095 }
00096 while ((dst - ret) & 3)
00097 *dst++ = '=';
00098 *dst = '\0';
00099
00100 return ret;
00101 }
00102
00103
00104
00105 #ifdef TEST_BASE64
00106 #include "avutil.h"
00107
00108 int b64test()
00109 {
00110 int numerr = 0;
00111 int len;
00112 int numtest = 1;
00113 uint8_t decode[1000];
00114 struct test {
00115 void *data;
00116 int len;
00117 const char *result;
00118 } *t, tests[] = {
00119 {
00120 "", 0, ""}, {
00121 "1", 1, "MQ=="}, {
00122 "22", 2, "MjI="}, {
00123 "333", 3, "MzMz"}, {
00124 "4444", 4, "NDQ0NA=="}, {
00125 "55555", 5, "NTU1NTU="}, {
00126 "abc:def", 7, "YWJjOmRlZg=="}, {
00127 NULL}
00128 };
00129 for (t = tests; t->data; t++) {
00130 char *str;
00131
00132 av_log(NULL, AV_LOG_ERROR, "Encoding %s...\n", (char *) t->data);
00133 str = av_base64_encode(t->data, t->len);
00134 if (str) {
00135 av_log(NULL, AV_LOG_ERROR, "Encoded to %s...\n", str);
00136 if (strcmp(str, t->result) != 0) {
00137 av_log(NULL, AV_LOG_ERROR, "failed test %d: %s != %s\n",
00138 numtest, str, t->result);
00139 numerr++;
00140 }
00141 av_free(str);
00142 }
00143
00144 av_log(NULL, AV_LOG_ERROR, "Done encoding, about to decode...\n");
00145 len = av_base64_decode(decode, t->result, sizeof(decode));
00146 if (len != t->len) {
00147 av_log(NULL, AV_LOG_ERROR, "failed test %d: len %d != %d\n",
00148 numtest, len, t->len);
00149 numerr++;
00150 } else if (memcmp(decode, t->data, t->len) != 0) {
00151 av_log(NULL, AV_LOG_ERROR, "failed test %d: data\n", numtest);
00152 numerr++;
00153 } else {
00154 av_log(NULL, AV_LOG_ERROR, "Decoded to %s\n",
00155 (char *) t->data);
00156 }
00157 numtest++;
00158 }
00159
00160 #undef srand
00161 #undef rand
00162
00163 {
00164 int test_count;
00165 srand(123141);
00166 for (test_count = 0; test_count < 100; test_count++) {
00167 int size = rand() % 1024;
00168 int ii;
00169 uint8_t *data;
00170 char *encoded_result;
00171
00172 av_log(NULL, AV_LOG_ERROR, "Test %d: Size %d bytes...",
00173 test_count, size);
00174 data = (uint8_t *) av_malloc(size);
00175 for (ii = 0; ii < size; ii++) {
00176 data[ii] = rand() % 255;
00177 }
00178
00179 encoded_result = av_base64_encode(data, size);
00180 if (encoded_result) {
00181 int decode_buffer_size = size + 10;
00182 uint8_t *decode_buffer = av_malloc(decode_buffer_size);
00183 if (decode_buffer) {
00184 int decoded_size =
00185 av_base64_decode(decode_buffer, encoded_result,
00186 decode_buffer_size);
00187
00188 if (decoded_size != size) {
00189 av_log(NULL, AV_LOG_ERROR,
00190 "Decoded/Encoded size mismatch (%d != %d)\n",
00191 decoded_size, size);
00192 } else {
00193 if (memcmp(decode_buffer, data, decoded_size) == 0) {
00194 av_log(NULL, AV_LOG_ERROR, "Passed!\n");
00195 } else {
00196 av_log(NULL, AV_LOG_ERROR,
00197 "Failed (Data differs)!\n");
00198 }
00199 }
00200 av_free(decode_buffer);
00201 }
00202
00203 av_free(encoded_result);
00204 }
00205 }
00206 }
00207
00208
00209 {
00210 uint8_t str[32];
00211 if (av_base64_decode(str, "M=M=", sizeof(str)) != -1) {
00212 av_log(NULL, AV_LOG_ERROR,
00213 "failed test %d: successful decode of `M=M='\n",
00214 numtest++);
00215 numerr++;
00216 }
00217 if (av_base64_decode(str, "MQ===", sizeof(str)) != -1) {
00218 av_log(NULL, AV_LOG_ERROR,
00219 "failed test %d: successful decode of `MQ==='\n",
00220 numtest++);
00221 numerr++;
00222 }
00223 }
00224
00225 return numerr;
00226 }
00227 #endif
00228