00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <stdio.h>
00021 #include <assert.h>
00022 #include "inet/base64.h"
00023
00024 static char base64_table[] =
00025 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
00026 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
00027 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
00028 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
00029 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
00030 };
00031
00032 static char base64_pad = '=';
00033
00051 unsigned char *base64encode(const unsigned char *str,
00052 unsigned length,
00053 unsigned *ret_length)
00054 {
00055 const unsigned char *current = str;
00056 unsigned char *result;
00057
00058 result = (unsigned char *)malloc((length+3 - length%3)*4/3 + 1);
00059 if (!result)
00060 return NULL;
00061
00062
00063
00064 unsigned i = 0;
00065
00066 while (length > 2) {
00067 result[i++] = base64_table[current[0] >> 2];
00068 result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
00069 result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
00070 result[i++] = base64_table[current[2] & 0x3f];
00071
00072 current += 3;
00073 length -= 3;
00074 }
00075
00076
00077
00078 if (length != 0) {
00079 result[i++] = base64_table[current[0] >> 2];
00080 if (length > 1) {
00081 result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
00082 result[i++] = base64_table[(current[1] & 0x0f) << 2];
00083 result[i++] = base64_pad;
00084 }
00085 else {
00086 result[i++] = base64_table[(current[0] & 0x03) << 4];
00087 result[i++] = base64_pad;
00088 result[i++] = base64_pad;
00089 }
00090 }
00091 if(ret_length)
00092 *ret_length = i;
00093
00094 result[i]='\0';
00095 return result;
00096 }
00097
00098
00116 unsigned char *base64decode( const unsigned char *str,
00117 unsigned length,
00118 unsigned *ret_length)
00119 {
00120 static int reverse_table[256];
00121 static bool table_built = false;
00122
00123 if (!table_built) {
00124 for(int ch = 0; ch < 256; ch++) {
00125 char *chp = strchr(base64_table, ch);
00126 if (chp) {
00127 reverse_table[ch] = (int)(chp - base64_table);
00128 }
00129 else
00130 reverse_table[ch] = -1;
00131 }
00132 table_built = true;
00133 }
00134
00135 unsigned char *result;
00136 result = (unsigned char *)malloc(length + 1);
00137 if (result == NULL)
00138 return NULL;
00139
00140
00141
00142 const unsigned char *current = str;
00143 int ch, i = 0, j = 0, k;
00144
00145
00146 while ((ch = *current++) != '\0') {
00147 if (ch == base64_pad)
00148 break;
00149
00150
00151
00152
00153
00154
00155
00156 if (ch == ' ')
00157 ch = '+';
00158
00159 ch = reverse_table[ch];
00160 if (ch < 0)
00161 continue;
00162
00163 switch(i % 4) {
00164 case 0:
00165 result[j] = ch << 2;
00166 break;
00167 case 1:
00168 result[j++] |= ch >> 4;
00169 result[j] = (ch & 0x0f) << 4;
00170 break;
00171 case 2:
00172 result[j++] |= ch >>2;
00173 result[j] = (ch & 0x03) << 6;
00174 break;
00175 case 3:
00176 result[j++] |= ch;
00177 break;
00178 }
00179 i++;
00180 }
00181
00182
00183
00184 k = j;
00185 if (ch == base64_pad) {
00186 switch(i % 4) {
00187 case 0:
00188 case 1:
00189 free(result);
00190 return NULL;
00191 case 2:
00192 k++;
00193 case 3:
00194 result[k++] = 0;
00195 }
00196 }
00197 assert(j<length);
00198
00199 if (ret_length)
00200 *ret_length = j;
00201
00202 result[k] = '\0';
00203 return result;
00204 }
00205