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;
00046 olen += olen / 72;
00047 olen++;
00048 if (olen < len)
00049 return NULL;
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
00193