00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: base64.c,v 1.4 2007-08-18 22:32:23 sven Exp $";
00022 #endif
00023
00024 #include <stdlib.h>
00025 #include "base64.h"
00026
00027 static char *b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00028
00029 char *b64enc(const unsigned char *data, int len)
00030 {
00031 char *dest;
00032
00033 dest = malloc(4 * len / 3 + 4);
00034 b64enc_buf(data, len, dest);
00035 return(dest);
00036 }
00037
00038 int b64enc_buf(const unsigned char *data, int len, char *dest)
00039 {
00040 char *buf = dest;
00041
00042
00043 while (len >= 3) {
00044 buf[0] = b64chars[(data[0] >> 2) & 0x3f];
00045 buf[1] = b64chars[((data[0] << 4) & 0x30) | ((data[1] >> 4) & 0xf)];
00046 buf[2] = b64chars[((data[1] << 2) & 0x3c) | ((data[2] >> 6) & 0x3)];
00047 buf[3] = b64chars[data[2] & 0x3f];
00048 data += 3;
00049 buf += 4;
00050 len -= 3;
00051 }
00052
00053 if (len > 0) {
00054 buf[0] = b64chars[(data[0] >> 2) & 0x3f];
00055 buf[1] = b64chars[(data[0] << 4) & 0x30];
00056 if (len > 1) {
00057 buf[1] += (data[1] >> 4) & 0xf;
00058 buf[2] = b64chars[(data[1] << 2) & 0x3c];
00059 }
00060 else buf[2] = '=';
00061 buf[3] = '=';
00062 buf += 4;
00063 }
00064
00065 *buf = '\0';
00066 return(buf - dest);
00067 }
00068
00069 char *b64dec(const unsigned char *data, int len)
00070 {
00071 char *dest;
00072
00073 dest = malloc(len+1);
00074 b64dec_buf(data, len, dest);
00075 return(dest);
00076 }
00077
00078 int b64dec_buf(const unsigned char *data, int len, char *dest)
00079 {
00080 unsigned char c;
00081 int cur = 0, val = 0, i = 0;
00082
00083 while (len) {
00084 c = *data;
00085 len--;
00086 data++;
00087
00088 if (c >= 'A' && c <= 'Z') val = c - 'A';
00089 else if (c >= 'a' && c <= 'z') val = c - 'a' + 26;
00090 else if (c >= '0' && c <= '9') val = c - '0' + 52;
00091 else if (c == '+') val = 62;
00092 else if (c == '/') val = 63;
00093 else if (c == '=') break;
00094 else continue;
00095
00096 switch (cur++) {
00097 case 0:
00098 dest[i] = (val << 2) & 0xfc;
00099 break;
00100 case 1:
00101 dest[i] |= (val >> 4) & 0x03;
00102 i++;
00103 dest[i] = (val << 4) & 0xf0;
00104 break;
00105 case 2:
00106 dest[i] |= (val >> 2) & 0x0f;
00107 i++;
00108 dest[i] = (val << 6) & 0xc0;
00109 break;
00110 case 3:
00111 dest[i] |= val & 0x3f;
00112 i++;
00113 cur = 0;
00114 break;
00115 }
00116 }
00117 dest[i] = 0;
00118 return(i);
00119 }
00120 static char base64to[256] = {
00121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00124 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
00125 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
00126 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 62, 0, 63, 0, 0,
00127 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00128 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0,
00129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00137 };
00138
00139 static int tobase64[64] = {
00140 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
00141 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
00142 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
00143 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '[', ']'
00144 };
00145
00156 int b64dec_int(const char *b)
00157 {
00158 int i = 0;
00159
00160 while (*b) i = (i << 6) + base64to[(unsigned char) *b++];
00161 return i;
00162 }
00163
00177 const char *b64enc_int(int i)
00178 {
00179 char *pos;
00180 static char ret[12];
00181
00182 pos = ret + 11;
00183 *pos = 0;
00184
00185 do {
00186 --pos;
00187 *pos = tobase64[i & 0x3F];
00188 i >>= 6;
00189 } while (i);
00190
00191 return pos;
00192 }