base64.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "os.h"
00019 #include "base64.h"
00020 
00021 static const unsigned char base64_table[65] =
00022         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00023 
00037 unsigned char * base64_encode(const unsigned char *src, size_t len,
00038                               size_t *out_len)
00039 {
00040         unsigned char *out, *pos;
00041         const unsigned char *end, *in;
00042         size_t olen;
00043         int line_len;
00044 
00045         olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
00046         olen += olen / 72; /* line feeds */
00047         olen++; /* nul termination */
00048         if (olen < len)
00049                 return NULL; /* integer overflow */
00050         out = os_malloc(olen);
00051         if (out == NULL)
00052                 return NULL;
00053 
00054         end = src + len;
00055         in = src;
00056         pos = out;
00057         line_len = 0;
00058         while (end - in >= 3) {
00059                 *pos++ = base64_table[in[0] >> 2];
00060                 *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
00061                 *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
00062                 *pos++ = base64_table[in[2] & 0x3f];
00063                 in += 3;
00064                 line_len += 4;
00065                 if (line_len >= 72) {
00066                         *pos++ = '\n';
00067                         line_len = 0;
00068                 }
00069         }
00070 
00071         if (end - in) {
00072                 *pos++ = base64_table[in[0] >> 2];
00073                 if (end - in == 1) {
00074                         *pos++ = base64_table[(in[0] & 0x03) << 4];
00075                         *pos++ = '=';
00076                 } else {
00077                         *pos++ = base64_table[((in[0] & 0x03) << 4) |
00078                                               (in[1] >> 4)];
00079                         *pos++ = base64_table[(in[1] & 0x0f) << 2];
00080                 }
00081                 *pos++ = '=';
00082                 line_len += 4;
00083         }
00084 
00085         if (line_len)
00086                 *pos++ = '\n';
00087 
00088         *pos = '\0';
00089         if (out_len)
00090                 *out_len = pos - out;
00091         return out;
00092 }
00093 
00094 
00106 unsigned char * base64_decode(const unsigned char *src, size_t len,
00107                               size_t *out_len)
00108 {
00109         unsigned char dtable[256], *out, *pos, in[4], block[4], tmp;
00110         size_t i, count, olen;
00111 
00112         os_memset(dtable, 0x80, 256);
00113         for (i = 0; i < sizeof(base64_table) - 1; i++)
00114                 dtable[base64_table[i]] = (unsigned char) i;
00115         dtable['='] = 0;
00116 
00117         count = 0;
00118         for (i = 0; i < len; i++) {
00119                 if (dtable[src[i]] != 0x80)
00120                         count++;
00121         }
00122 
00123         if (count == 0 || count % 4)
00124                 return NULL;
00125 
00126         olen = count / 4 * 3;
00127         pos = out = os_malloc(olen);
00128         if (out == NULL)
00129                 return NULL;
00130 
00131         count = 0;
00132         for (i = 0; i < len; i++) {
00133                 tmp = dtable[src[i]];
00134                 if (tmp == 0x80)
00135                         continue;
00136 
00137                 in[count] = src[i];
00138                 block[count] = tmp;
00139                 count++;
00140                 if (count == 4) {
00141                         *pos++ = (block[0] << 2) | (block[1] >> 4);
00142                         *pos++ = (block[1] << 4) | (block[2] >> 2);
00143                         *pos++ = (block[2] << 6) | block[3];
00144                         count = 0;
00145                 }
00146         }
00147 
00148         if (pos > out) {
00149                 if (in[2] == '=')
00150                         pos -= 2;
00151                 else if (in[3] == '=')
00152                         pos--;
00153         }
00154 
00155         *out_len = pos - out;
00156         return out;
00157 }
00158 
00159 
00160 #ifdef TEST_MAIN
00161 
00162 int main(int argc, char *argv[])
00163 {
00164         FILE *f;
00165         size_t len, elen;
00166         unsigned char *buf, *e;
00167 
00168         if (argc != 4) {
00169                 printf("Usage: base64 <encode|decode> <in file> <out file>\n");
00170                 return -1;
00171         }
00172 
00173         buf = os_readfile(argv[2], &len);
00174         if (buf == NULL)
00175                 return -1;
00176 
00177         if (strcmp(argv[1], "encode") == 0)
00178                 e = base64_encode(buf, len, &elen);
00179         else
00180                 e = base64_decode(buf, len, &elen);
00181         if (e == NULL)
00182                 return -2;
00183         f = fopen(argv[3], "w");
00184         if (f == NULL)
00185                 return -3;
00186         fwrite(e, 1, elen, f);
00187         fclose(f);
00188         free(e);
00189 
00190         return 0;
00191 }
00192 #endif /* TEST_MAIN */
00193 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:53 2009 for hostapd by  doxygen 1.6.1