• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavutil/base64.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
00003  *
00004  * This file is part of FFmpeg.
00005  *
00006  * FFmpeg is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * FFmpeg is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with FFmpeg; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00027 #include "common.h"
00028 #include "base64.h"
00029 
00030 /* ---------------- private code */
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 * b64_encode: Stolen from VLC's http.c.
00068 * Simplified by Michael.
00069 * Fixed edge cases and made it work from data (vs. strings) by Ryan.
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

Generated on Sat Feb 16 2013 09:23:15 for ffmpeg by  doxygen 1.7.1