Google
Web alhem.net

Base64.cpp

Go to the documentation of this file.
00001 // Base64.cpp
00002 /*
00003 This program is free software; you can redistribute it and/or
00004 modify it under the terms of the GNU General Public License
00005 as published by the Free Software Foundation; either version 2
00006 of the License, or (at your option) any later version.
00007 
00008 This program is distributed in the hope that it will be useful,
00009 but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 GNU General Public License for more details.
00012 
00013 You should have received a copy of the GNU General Public License
00014 along with this program; if not, write to the Free Software
00015 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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); // 0..63
00055         }
00056 }
00057 
00058 
00059 char Base64::setupdecode(char c)
00060 {
00061         if (c >= 'a')
00062                 return (char)((c + 26) - 'a');  // 26..51
00063         if (c >= 'A')
00064                 return (char)(c - 'A');         // 0..25
00065         if (c >= '0')
00066                 return (char)((c + 52) - '0');  // 52..61
00067         if (c == '+')
00068                 return 62;              // 62
00069         if (c == '/')
00070                 return 63;              // 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 //                      fwrite(output, 1, l, fil2);
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 } // namespace

Generated for cgi++ by doxygen 1.3.7

Page, code, and content Copyright (C) 2004 by Anders Hedström