00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include "nanohttp-base64.h"
00029
00030 static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00031
00032 static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
00033
00039 static void _encodeblock(unsigned char in[3], unsigned char out[4], int len)
00040 {
00041
00042 out[0] = cb64[in[0] >> 2];
00043 out[1] = cb64[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
00044 out[2] = (unsigned char)(len > 1 ? cb64[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)] : '=');
00045 out[3] = (unsigned char)(len > 2 ? cb64[in[2] & 0x3f] : '=');
00046
00047 return;
00048 }
00049
00050 void base64_encode_string(const unsigned char *instr, unsigned char *outstr)
00051 {
00052 unsigned char in[3], out[4];
00053 int i, len;
00054
00055 while (*instr)
00056 {
00057 len = 0;
00058 for (i = 0; i < 3; i++)
00059 {
00060 if ((in[i] = (unsigned char)*instr))
00061 {
00062 len++;
00063 instr++;
00064 }
00065 }
00066 if (len)
00067 {
00068 _encodeblock(in, out, len);
00069 for (i = 0; i < 4; i++)
00070 *outstr++ = out[i];
00071 }
00072 }
00073 }
00074
00080 static void _decodeblock(unsigned char in[4], unsigned char out[3])
00081 {
00082 out[0] = (unsigned char)(in[0] << 2 | in[1] >> 4);
00083 out[1] = (unsigned char)(in[1] << 4 | in[2] >> 2);
00084 out[2] = (unsigned char)(((in[2] << 6) & 0xc0) | in[3]);
00085
00086 return;
00087 }
00088
00092 void base64_decode_string(const unsigned char *instr, unsigned char *outstr)
00093 {
00094 unsigned char in[4], out[3], v;
00095 int i, len;
00096
00097 while (*instr)
00098 {
00099 for (len = 0, i = 0; i < 4 && *instr; i++)
00100 {
00101 v = 0;
00102 while (*instr && v == 0)
00103 {
00104 v = *instr++;
00105 v = (unsigned char)((v < 43 || v > 122) ? 0 : cd64[v - 43]);
00106 if (v)
00107 v = (unsigned char)((v == '$') ? 0 : v - 61);
00108 }
00109 if (*instr)
00110 {
00111 len++;
00112 if (v)
00113 in[i] = (unsigned char)(v - 1);
00114 }
00115 else
00116 {
00117 in[i] = 0;
00118 }
00119 }
00120 if (len)
00121 {
00122 _decodeblock(in, out);
00123 for (i = 0; i < len - 1; i++)
00124 *outstr++ = out[i];
00125 }
00126 }
00127 }
00128
00129 #ifdef BASE64_TEST_CASE_FROM_RFC2617
00130 #include <stdio.h>
00131 #include <strings.h>
00132 int main(int argc, char **argv) {
00133
00134 unsigned char *instr = "QWxhZGRpbjpvcGVuIHNlc2FtZQ==";
00135 unsigned char *result = "Aladdin:open sesame";
00136 unsigned char instr2[80];
00137 unsigned char outstr[80];
00138
00139 bzero(outstr, 80);
00140 base64_decode_string(instr, outstr);
00141
00142 printf("\"%s\" => \"%s\"\n", instr, outstr);
00143 if (strcmp(outstr, result))
00144 printf("base64_decode failed\n");
00145
00146 strcpy(instr2, outstr);
00147
00148 bzero(outstr, 80);
00149 base64_encode_string(instr2, outstr);
00150
00151 printf("\"%s\" => \"%s\"\n", instr2, outstr);
00152 if (strcmp(outstr, instr))
00153 printf("base64_encode failed\n");
00154
00155 return 0;
00156 }
00157 #endif