00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef _WIN32
00019 #pragma warning(disable:4786)
00020 #endif
00021 #include <stdio.h>
00022 #include <string.h>
00023
00024 #include "Base64.h"
00025
00026
00027 static char base64vec[128];
00028
00029 static const unsigned char g_achEncodeTable[64] =
00030 {
00031 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
00032 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
00033 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
00034 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
00035 };
00036
00037 namespace Cgi {
00038
00039 Base64::Base64(char eq) : m_eqchar(eq)
00040 {
00041 setupbase64();
00042 }
00043
00044
00045 Base64::~Base64()
00046 {
00047 }
00048
00049
00050 void Base64::setupbase64()
00051 {
00052 for (char c = 0; c <= 'z'; c++)
00053 {
00054 base64vec[ (int)c] = setupdecode(c);
00055 }
00056 }
00057
00058
00059 char Base64::setupdecode(char c)
00060 {
00061 if (c >= 'a')
00062 return (char)((c + 26) - 'a');
00063 if (c >= 'A')
00064 return (char)(c - 'A');
00065 if (c >= '0')
00066 return (char)((c + 52) - '0');
00067 if (c == '+')
00068 return 62;
00069 if (c == '/')
00070 return 63;
00071 return 0;
00072 }
00073
00074
00075 unsigned char Base64::reverse(char c)
00076 {
00077 return g_achEncodeTable[(int)c];
00078 }
00079
00080
00081 void Base64::encode(const char *in,char *out)
00082 {
00083 int i1 = (in[0] >> 2) & 63;
00084 int i2 = ( ((in[0] & 3) << 4) + ((in[1] >> 4) & 15) ) & 63;
00085 int i3 = ( ((in[1] & 15) << 2) + ((in[2] >> 6) & 3) ) & 63;
00086 int i4 = in[2] & 63;
00087
00088 out[0] = reverse( (char)i1);
00089 out[1] = reverse( (char)i2);
00090 out[2] = reverse( (char)i3);
00091 out[3] = reverse( (char)i4);
00092 }
00093
00094
00095 int Base64::decode(char c)
00096 {
00097 return base64vec[(int)c];
00098 }
00099
00100
00101 void Base64::decode_string(char *s, unsigned char *output, int &l)
00102 {
00103 union {
00104 unsigned long l;
00105 char s[4];
00106 } u;
00107
00108 if (s[2] == m_eqchar)
00109 {
00110 l = 1;
00111 u.l = decode(s[0]) << 18 | decode(s[1]) << 12;
00112
00113 output[0] = u.s[2];
00114 output[1] = 0;
00115 output[2] = 0;
00116 return;
00117 }
00118 else
00119 if (s[3] == m_eqchar)
00120 {
00121 l = 2;
00122 u.l = decode(s[0]) << 18 | decode(s[1]) << 12 | decode(s[2]) << 6;
00123
00124 output[0] = u.s[2];
00125 output[1] = u.s[1];
00126 output[2] = 0;
00127 return;
00128 }
00129 l = 3;
00130 u.l = decode(s[0]) << 18 | decode(s[1]) << 12 | decode(s[2]) << 6 | decode(s[3]);
00131
00132 output[0] = u.s[2];
00133 output[1] = u.s[1];
00134 output[2] = u.s[0];
00135 }
00136
00137
00138 void Base64::encode_file(const char *s,const char *outfn)
00139 {
00140 FILE *fil;
00141 FILE *fil2;
00142 int iptr = 0;
00143 int ptr = 0;
00144 size_t dv = 0;
00145 unsigned char c;
00146 char tmp[4];
00147 char slask[200];
00148
00149 slask[76] = 0;
00150
00151 if ((fil = fopen(s, "rb")) != NULL)
00152 {
00153 fil2 = fopen(outfn, "wt");
00154 fread(&c,1,1,fil);
00155 while (!feof(fil))
00156 {
00157 tmp[iptr++] = c;
00158 if (iptr == 3)
00159 {
00160 encode(tmp, slask + ptr);
00161 ptr += 4;
00162 if (ptr == 76)
00163 {
00164 fprintf(fil2,"%s\n",slask);
00165 ptr = 0;
00166 }
00167 iptr = 0;
00168 dv++;
00169 }
00170 fread(&c,1,1,fil);
00171 }
00172 fclose(fil);
00173
00174 if (iptr)
00175 {
00176 int i = iptr;
00177 while (iptr < 3)
00178 tmp[iptr++] = 0;
00179 encode(tmp, slask + ptr);
00180 switch (i)
00181 {
00182 case 1:
00183 slask[ptr + 2] = m_eqchar;
00184 case 2:
00185 slask[ptr + 3] = m_eqchar;
00186 }
00187 ptr += 4;
00188 if (ptr == 76)
00189 {
00190 fprintf(fil2,"%s\n",slask);
00191 ptr = 0;
00192 }
00193 }
00194 if (ptr)
00195 {
00196 slask[ptr] = 0;
00197 fprintf(fil2,"%s\n",slask);
00198 ptr = 0;
00199 }
00200 fclose(fil2);
00201 }
00202 }
00203
00204
00205 void Base64::encode64(const char *in,size_t len,std::vector<std::string> &out)
00206 {
00207 size_t dv = len / 3;
00208 size_t ptr = 0;
00209 size_t i;
00210 char tmp[100];
00211
00212 tmp[76] = 0;
00213 for (i = 0; i < dv; i++)
00214 {
00215 encode(in + i * 3,tmp + ptr);
00216 ptr += 4;
00217 tmp[ptr] = 0;
00218 if (ptr == 76)
00219 {
00220 out.push_back( tmp );
00221 ptr = 0;
00222 }
00223 }
00224 if (len % 3)
00225 {
00226 char slask[3];
00227
00228 memset(slask,0,3);
00229 memmove(slask,in + i * 3,len % 3);
00230
00231 encode(slask,tmp + ptr);
00232 switch (len % 3)
00233 {
00234 case 1:
00235 tmp[ptr + 2] = m_eqchar;
00236 case 2:
00237 tmp[ptr + 3] = m_eqchar;
00238 }
00239 ptr += 4;
00240 tmp[ptr] = 0;
00241 if (ptr == 76)
00242 {
00243 out.push_back( tmp );
00244 ptr = 0;
00245 }
00246 }
00247 if (ptr)
00248 {
00249 tmp[ptr] = 0;
00250 out.push_back( tmp );
00251 ptr = 0;
00252 }
00253 }
00254
00255
00256 std::string Base64::encode_buffer(const std::string& buf)
00257 {
00258 const char *in = buf.c_str();
00259 size_t len = buf.size();
00260 std::string out;
00261 size_t dv = len / 3;
00262 size_t ptr = 0;
00263 size_t i;
00264 char tmp[100];
00265
00266 tmp[76] = 0;
00267 for (i = 0; i < dv; i++)
00268 {
00269 encode(in + i * 3,tmp + ptr);
00270 ptr += 4;
00271 tmp[ptr] = 0;
00272 if (ptr == 76)
00273 {
00274 out += tmp;
00275 ptr = 0;
00276 }
00277 }
00278 if (len % 3)
00279 {
00280 char slask[3];
00281
00282 memset(slask,0,3);
00283 memmove(slask,in + i * 3,len % 3);
00284
00285 encode(slask,tmp + ptr);
00286 switch (len % 3)
00287 {
00288 case 1:
00289 tmp[ptr + 2] = m_eqchar;
00290 case 2:
00291 tmp[ptr + 3] = m_eqchar;
00292 }
00293 ptr += 4;
00294 tmp[ptr] = 0;
00295 if (ptr == 76)
00296 {
00297 out += tmp;
00298 ptr = 0;
00299 }
00300 }
00301 if (ptr)
00302 {
00303 tmp[ptr] = 0;
00304 out += tmp;
00305 ptr = 0;
00306 }
00307 return out;
00308 }
00309
00310
00311 void Base64::encode_from_file(const char *fn,std::vector<std::string> &out)
00312 {
00313 FILE *fil;
00314 int iptr = 0;
00315 int ptr = 0;
00316 size_t dv = 0;
00317 unsigned char c;
00318 char tmp[4];
00319 char slask[200];
00320
00321 slask[76] = 0;
00322
00323 if ((fil = fopen(fn, "rb")) != NULL)
00324 {
00325 fread(&c,1,1,fil);
00326 while (!feof(fil))
00327 {
00328 tmp[iptr++] = c;
00329 if (iptr == 3)
00330 {
00331 encode(tmp, slask + ptr);
00332 ptr += 4;
00333 if (ptr == 76)
00334 {
00335 out.push_back( slask );
00336 ptr = 0;
00337 }
00338 iptr = 0;
00339 dv++;
00340 }
00341 fread(&c,1,1,fil);
00342 }
00343 fclose(fil);
00344
00345 if (iptr)
00346 {
00347 int i = iptr;
00348 while (iptr < 3)
00349 tmp[iptr++] = 0;
00350 encode(tmp, slask + ptr);
00351 switch (i)
00352 {
00353 case 1:
00354 slask[ptr + 2] = m_eqchar;
00355 case 2:
00356 slask[ptr + 3] = m_eqchar;
00357 }
00358 ptr += 4;
00359 if (ptr == 76)
00360 {
00361 out.push_back( slask );
00362 ptr = 0;
00363 }
00364 }
00365 if (ptr)
00366 {
00367 slask[ptr] = 0;
00368 out.push_back( slask );
00369 ptr = 0;
00370 }
00371 }
00372 }
00373
00374
00375 void Base64::decode_file(char *s,char *outfn)
00376 {
00377 FILE *fil;
00378 FILE *fil2;
00379 char slask[200];
00380 unsigned char output[200];
00381
00382 if ((fil = fopen(s, "rt")) != NULL)
00383 {
00384 fil2 = fopen(outfn, "wb");
00385 fgets(slask, 200, fil);
00386 while (!feof(fil))
00387 {
00388 while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10))
00389 {
00390 slask[strlen(slask) - 1] = 0;
00391 }
00392 for (int i = 0; i < (int)strlen(slask); i += 4)
00393 {
00394 int l;
00395 decode_string(slask + i, output, l);
00396 fwrite(output, 1, l, fil2);
00397 }
00398
00399 fgets(slask, 200, fil);
00400 }
00401 fclose(fil);
00402 fclose(fil2);
00403 }
00404 }
00405
00406
00407 void Base64::decode_to_file(std::vector<std::string> &body,char *outfn)
00408 {
00409 FILE *fil;
00410 unsigned char out[4];
00411
00412 if ((fil = fopen(outfn,"wb")) != NULL)
00413 {
00414 for (std::vector<std::string>::iterator it = body.begin(); it != body.end(); it++)
00415 {
00416 for (size_t i = 0; i < (*it).size(); i += 4)
00417 {
00418 int l;
00419 decode_string( (char *)(*it).c_str() + i, out, l);
00420 fwrite(out, 1, l, fil);
00421 }
00422 }
00423 fclose(fil);
00424 }
00425 }
00426
00427
00428 void Base64::decode_stdout(char *s,FILE *fil2)
00429 {
00430 FILE *fil;
00431 char slask[200];
00432 unsigned char output[200];
00433
00434 if ((fil = fopen(s, "rt")) != NULL)
00435 {
00436 fgets(slask, 200, fil);
00437 while (!feof(fil))
00438 {
00439 while (strlen(slask) && (slask[strlen(slask) - 1] == 13 || slask[strlen(slask) - 1] == 10))
00440 {
00441 slask[strlen(slask) - 1] = 0;
00442 }
00443 for (int i = 0; i < (int)strlen(slask); i += 4)
00444 {
00445 int l;
00446 decode_string(slask + i, output, l);
00447 fwrite(output, 1, l, fil2);
00448 }
00449
00450 fgets(slask, 200, fil);
00451 }
00452 fclose(fil);
00453 }
00454 }
00455
00456
00457 void Base64::decode_to_stdout(const std::string &str,FILE *fil2)
00458 {
00459 size_t p = 0;
00460 char slask[20000];
00461 unsigned char output[200];
00462
00463 while (p < str.size())
00464 {
00465 size_t i = 0;
00466 while (str[p] != 13 && str[p] != 10 && p < str.size())
00467 {
00468 slask[i++] = str[p++];
00469 }
00470 slask[i] = 0;
00471 while (str[p] == 13 || str[p] == 10)
00472 p++;
00473 for (i = 0; i < strlen(slask); i += 4)
00474 {
00475 int l;
00476 decode_string(slask + i, output, l);
00477 fwrite(output, 1, l, fil2);
00478 }
00479 }
00480 }
00481
00482
00483 void Base64::decode_to_stdout(std::vector<std::string> &body,FILE *fil)
00484 {
00485 unsigned char out[4];
00486
00487 for (std::vector<std::string>::iterator it = body.begin(); it != body.end(); it++)
00488 {
00489 for (size_t i = 0; i < (*it).size(); i += 4)
00490 {
00491 int l;
00492 decode_string( (char *)(*it).c_str() + i, out, l);
00493 fwrite(out, 1, l, fil);
00494 }
00495 }
00496 }
00497
00498
00499 size_t Base64::decode_length(const std::string &str)
00500 {
00501 size_t p = 0;
00502 size_t len = 0;
00503 char slask[20000];
00504 unsigned char output[200];
00505
00506 while (p < str.size())
00507 {
00508 size_t i = 0;
00509 while (str[p] != 13 && str[p] != 10 && p < str.size())
00510 {
00511 slask[i++] = str[p++];
00512 }
00513 slask[i] = 0;
00514 while (str[p] == 13 || str[p] == 10)
00515 p++;
00516 for (i = 0; i < strlen(slask); i += 4)
00517 {
00518 int l;
00519 decode_string(slask + i, output, l);
00520
00521 len += l;
00522 }
00523 }
00524 return len;
00525 }
00526
00527
00528 void Base64::decode_to_buffer(const std::string& str,char *ut,size_t max)
00529 {
00530 size_t p = 0;
00531 size_t o = 0;
00532 char slask[20000];
00533 unsigned char output[200];
00534
00535 while (p < str.size())
00536 {
00537 size_t i = 0;
00538 while (str[p] != 13 && str[p] != 10 && p < str.size())
00539 {
00540 slask[i++] = str[p++];
00541 }
00542 slask[i] = 0;
00543 while (str[p] == 13 || str[p] == 10)
00544 p++;
00545 for (i = 0; i < strlen(slask); i += 4)
00546 {
00547 int l;
00548 decode_string(slask + i, output, l);
00549 if (o + l <= max)
00550 {
00551 memcpy(ut + o, output, l);
00552 if (o + l < max)
00553 memset(ut + o + l, 0, 1);
00554 }
00555 o += l;
00556 }
00557 }
00558 }
00559
00560
00561
00562 }