00001
00005 static int _debug = 0;
00006
00007 #include "system.h"
00008 #include "base64.h"
00009 #include "debug.h"
00010
00011 int B64decode (const char * s, void ** datap, size_t *lenp)
00012 {
00013 static char * b64dec = NULL;
00014 unsigned char *t, *te;
00015 size_t ns, nt;
00016 unsigned a, b, c, d;
00017
00018 if (s == NULL) return 1;
00019 ns = strlen(s);
00020 if (ns & 0x3) return 2;
00021
00022 if (b64dec == NULL) {
00023 b64dec = xmalloc(255);
00024 memset(b64dec, 0x80, 255);
00025 for (c = 'A'; c <= 'Z'; c++)
00026 b64dec[ c ] = 0 + (c - 'A');
00027 for (c = 'a'; c <= 'z'; c++)
00028 b64dec[ c ] = 26 + (c - 'a');
00029 for (c = '0'; c <= '9'; c++)
00030 b64dec[ c ] = 52 + (c - '0');
00031 b64dec[(unsigned)'+'] = 62;
00032 b64dec[(unsigned)'/'] = 63;
00033 b64dec[(unsigned)'='] = 0;
00034 }
00035
00036 nt = (ns / 4) * 3;
00037 t = te = xmalloc(nt + 1);
00038
00039 while (ns > 0) {
00040 if ((a = b64dec[ (unsigned)*s++ ]) == 0x80)
00041 break;
00042 if ((b = b64dec[ (unsigned)*s++ ]) == 0x80)
00043 break;
00044 if ((c = b64dec[ (unsigned)*s++ ]) == 0x80)
00045 break;
00046 if ((d = b64dec[ (unsigned)*s++ ]) == 0x80)
00047 break;
00048 if (_debug)
00049 fprintf(stderr, "%7u %02x %02x %02x %02x -> %02x %02x %02x\n",
00050 (unsigned)ns, a, b, c, d,
00051 (((a << 2) | (b >> 4)) & 0xff),
00052 (((b << 4) | (c >> 2)) & 0xff),
00053 (((c << 6) | d) & 0xff));
00054 ns -= 4;
00055 *te++ = (a << 2) | (b >> 4);
00056 if (s[-2] == '=') break;
00057 *te++ = (b << 4) | (c >> 2);
00058 if (s[-1] == '=') break;
00059 *te++ = (c << 6) | d;
00060 }
00061
00062 if (ns > 0) {
00063 free(t);
00064 return 3;
00065 }
00066 if (lenp)
00067 *lenp = (te - t);
00068 if (datap)
00069 *datap = t;
00070 else
00071 free(t);
00072
00073 return 0;
00074 }
00075
00076 char * B64encode (const void * str, size_t ns)
00077 {
00078 static char b64enc[] =
00079 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00080 const unsigned char *s = str;
00081 unsigned char *t, *te;
00082 size_t nt;
00083 unsigned c;
00084
00085 if (s == NULL) return NULL;
00086 if (*s == '\0') return xstrdup("");
00087
00088 if (ns == 0) ns = strlen(s);
00089 nt = ((ns + 2) / 3) * 4;
00090 t = te = xmalloc(nt + 1);
00091
00092 while (ns) {
00093
00094 if (_debug)
00095 fprintf(stderr, "%7u %02x %02x %02x -> %02x %02x %02x %02x\n",
00096 (unsigned)ns, (unsigned)s[0], (unsigned)s[1], (unsigned)s[2],
00097 (unsigned)(s[0] >> 2),
00098 (unsigned)((s[0] & 0x3) << 4) | (s[1] >> 4),
00099 (unsigned)((s[1] & 0xf) << 2) | (s[2] >> 6),
00100 (unsigned)(s[2]& 0x3f));
00101 c = *s++;
00102 *te++ = b64enc[ (c >> 2) ];
00103 *te++ = b64enc[ ((c & 0x3) << 4) | (*s >> 4) ];
00104 if (--ns <= 0) {
00105 *te++ = '=';
00106 *te++ = '=';
00107 continue;
00108 }
00109 c = *s++;
00110 *te++ = b64enc[ ((c & 0xf) << 2) | (*s >> 6) ];
00111 if (--ns <= 0) {
00112 *te++ = '=';
00113 continue;
00114 }
00115 *te++ = b64enc[ (int)(*s & 0x3f) ];
00116 s++;
00117 --ns;
00118 }
00119 *te = '\0';
00120 return t;
00121 }