00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "Base64.hh"
00022 #include <strDup.hh>
00023 #include <string.h>
00024
00025 static char base64DecodeTable[256];
00026
00027 static void initBase64DecodeTable() {
00028 int i;
00029 for (i = 0; i < 256; ++i) base64DecodeTable[i] = (char)0x80;
00030
00031
00032 for (i = 'A'; i <= 'Z'; ++i) base64DecodeTable[i] = 0 + (i - 'A');
00033 for (i = 'a'; i <= 'z'; ++i) base64DecodeTable[i] = 26 + (i - 'a');
00034 for (i = '0'; i <= '9'; ++i) base64DecodeTable[i] = 52 + (i - '0');
00035 base64DecodeTable[(unsigned char)'+'] = 62;
00036 base64DecodeTable[(unsigned char)'/'] = 63;
00037 base64DecodeTable[(unsigned char)'='] = 0;
00038 }
00039
00040 unsigned char* base64Decode(char* in, unsigned& resultSize,
00041 Boolean trimTrailingZeros) {
00042 static Boolean haveInitedBase64DecodeTable = False;
00043 if (!haveInitedBase64DecodeTable) {
00044 initBase64DecodeTable();
00045 haveInitedBase64DecodeTable = True;
00046 }
00047
00048 unsigned char* out = (unsigned char*)strDupSize(in);
00049 int k = 0;
00050 int const jMax = strlen(in) - 3;
00051
00052 for (int j = 0; j < jMax; j += 4) {
00053 char inTmp[4], outTmp[4];
00054 for (int i = 0; i < 4; ++i) {
00055 inTmp[i] = in[i+j];
00056 outTmp[i] = base64DecodeTable[(unsigned char)inTmp[i]];
00057 if ((outTmp[i]&0x80) != 0) outTmp[i] = 0;
00058 }
00059
00060 out[k++] = (outTmp[0]<<2) | (outTmp[1]>>4);
00061 out[k++] = (outTmp[1]<<4) | (outTmp[2]>>2);
00062 out[k++] = (outTmp[2]<<6) | outTmp[3];
00063 }
00064
00065 if (trimTrailingZeros) {
00066 while (k > 0 && out[k-1] == '\0') --k;
00067 }
00068 resultSize = k;
00069 unsigned char* result = new unsigned char[resultSize];
00070 memmove(result, out, resultSize);
00071 delete[] out;
00072
00073 return result;
00074 }
00075
00076 static const char base64Char[] =
00077 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00078
00079 char* base64Encode(char const* orig) {
00080 if (orig == NULL) return NULL;
00081
00082 unsigned const origLength = strlen(orig);
00083 unsigned const numOrig24BitValues = origLength/3;
00084 Boolean havePadding = origLength > numOrig24BitValues*3;
00085 Boolean havePadding2 = origLength == numOrig24BitValues*3 + 2;
00086 unsigned const numResultBytes = 4*(numOrig24BitValues + havePadding);
00087 char* result = new char[numResultBytes+1];
00088
00089
00090 unsigned i;
00091 for (i = 0; i < numOrig24BitValues; ++i) {
00092 result[4*i+0] = base64Char[(orig[3*i]>>2)&0x3F];
00093 result[4*i+1] = base64Char[(((orig[3*i]&0x3)<<4) | (orig[3*i+1]>>4))&0x3F];
00094 result[4*i+2] = base64Char[((orig[3*i+1]<<2) | (orig[3*i+2]>>6))&0x3F];
00095 result[4*i+3] = base64Char[orig[3*i+2]&0x3F];
00096 }
00097
00098
00099 if (havePadding) {
00100 result[4*i+0] = base64Char[(orig[3*i]>>2)&0x3F];
00101 result[4*i+1] = base64Char[(((orig[3*i]&0x3)<<4) | (orig[3*i+1]>>4))&0x3F];
00102 if (havePadding2) {
00103 result[4*i+2] = base64Char[(orig[3*i+1]<<2)&0x3F];
00104 } else {
00105 result[4*i+2] = '=';
00106 }
00107 result[4*i+3] = '=';
00108 }
00109
00110 result[numResultBytes] = '\0';
00111 return result;
00112 }