ZenLib
|
00001 // // 00002 // #### ### ## -= Base64 library =- // 00003 // # # # # # Base64.h - Base64 encoder/decoder // 00004 // #### #### # # // 00005 // # # # # ##### Encodes and decodes base64 strings // 00006 // # # # # # Ideas taken from work done by Bob Withers // 00007 // #### ### # R1 2002-05-07 by Markus Ewald // 00008 // // 00009 #ifndef B64_BASE64_H 00010 #define B64_BASE64_H 00011 00012 #include <string> 00013 00014 namespace Base64 { 00015 00016 /// Encode string to base64 00017 inline std::string encode(const std::string &sString); 00018 /// Encode base64 into string 00019 inline std::string decode(const std::string &sString); 00020 00021 }; // namespace Base64 00022 00023 // ####################################################################### // 00024 // # Base64::encode() # // 00025 // ####################################################################### // 00026 /** Encodes the specified string to base64 00027 00028 @param sString String to encode 00029 @return Base64 encoded string 00030 */ 00031 inline std::string Base64::encode(const std::string &sString) { 00032 static const std::string sBase64Table( 00033 // 0000000000111111111122222222223333333333444444444455555555556666 00034 // 0123456789012345678901234567890123456789012345678901234567890123 00035 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 00036 ); 00037 static const char cFillChar = '='; 00038 std::string::size_type nLength = sString.length(); 00039 std::string sResult; 00040 00041 // Allocate memory for the converted string 00042 sResult.reserve(nLength * 8 / 6 + 1); 00043 00044 for(std::string::size_type nPos = 0; nPos < nLength; nPos++) { 00045 char cCode; 00046 00047 // Encode the first 6 bits 00048 cCode = (sString[nPos] >> 2) & 0x3f; 00049 sResult.append(1, sBase64Table[cCode]); 00050 00051 // Encode the remaining 2 bits with the next 4 bits (if present) 00052 cCode = (sString[nPos] << 4) & 0x3f; 00053 if(++nPos < nLength) 00054 cCode |= (sString[nPos] >> 4) & 0x0f; 00055 sResult.append(1, sBase64Table[cCode]); 00056 00057 if(nPos < nLength) { 00058 cCode = (sString[nPos] << 2) & 0x3f; 00059 if(++nPos < nLength) 00060 cCode |= (sString[nPos] >> 6) & 0x03; 00061 00062 sResult.append(1, sBase64Table[cCode]); 00063 } else { 00064 ++nPos; 00065 sResult.append(1, cFillChar); 00066 } 00067 00068 if(nPos < nLength) { 00069 cCode = sString[nPos] & 0x3f; 00070 sResult.append(1, sBase64Table[cCode]); 00071 } else { 00072 sResult.append(1, cFillChar); 00073 } 00074 } 00075 00076 return sResult; 00077 } 00078 00079 // ####################################################################### // 00080 // # Base64::decode() # // 00081 // ####################################################################### // 00082 /** Decodes the specified base64 string 00083 00084 @param sString Base64 string to decode 00085 @return Decoded string 00086 */ 00087 inline std::string Base64::decode(const std::string &sString) { 00088 static const std::string::size_type np = std::string::npos; 00089 static const std::string::size_type DecodeTable[] = { 00090 // 0 1 2 3 4 5 6 7 8 9 00091 np, np, np, np, np, np, np, np, np, np, // 0 - 9 00092 np, np, np, np, np, np, np, np, np, np, // 10 - 19 00093 np, np, np, np, np, np, np, np, np, np, // 20 - 29 00094 np, np, np, np, np, np, np, np, np, np, // 30 - 39 00095 np, np, np, 62, np, np, np, 63, 52, 53, // 40 - 49 00096 54, 55, 56, 57, 58, 59, 60, 61, np, np, // 50 - 59 00097 np, np, np, np, np, 0, 1, 2, 3, 4, // 60 - 69 00098 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 70 - 79 00099 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 80 - 89 00100 25, np, np, np, np, np, np, 26, 27, 28, // 90 - 99 00101 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 100 - 109 00102 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // 110 - 119 00103 49, 50, 51, np, np, np, np, np, np, np, // 120 - 129 00104 np, np, np, np, np, np, np, np, np, np, // 130 - 139 00105 np, np, np, np, np, np, np, np, np, np, // 140 - 149 00106 np, np, np, np, np, np, np, np, np, np, // 150 - 159 00107 np, np, np, np, np, np, np, np, np, np, // 160 - 169 00108 np, np, np, np, np, np, np, np, np, np, // 170 - 179 00109 np, np, np, np, np, np, np, np, np, np, // 180 - 189 00110 np, np, np, np, np, np, np, np, np, np, // 190 - 199 00111 np, np, np, np, np, np, np, np, np, np, // 200 - 209 00112 np, np, np, np, np, np, np, np, np, np, // 210 - 219 00113 np, np, np, np, np, np, np, np, np, np, // 220 - 229 00114 np, np, np, np, np, np, np, np, np, np, // 230 - 239 00115 np, np, np, np, np, np, np, np, np, np, // 240 - 249 00116 np, np, np, np, np, np // 250 - 256 00117 }; 00118 static const char cFillChar = '='; 00119 00120 std::string::size_type nLength = sString.length(); 00121 std::string sResult; 00122 00123 sResult.reserve(nLength); 00124 00125 for(std::string::size_type nPos = 0; nPos < nLength; nPos++) { 00126 unsigned char c, c1; 00127 00128 c = (char) DecodeTable[(unsigned char)sString[nPos]]; 00129 nPos++; 00130 c1 = (char) DecodeTable[(unsigned char)sString[nPos]]; 00131 c = (c << 2) | ((c1 >> 4) & 0x3); 00132 sResult.append(1, c); 00133 00134 if(++nPos < nLength) { 00135 c = sString[nPos]; 00136 if(cFillChar == c) 00137 break; 00138 00139 c = (char) DecodeTable[(unsigned char)sString[nPos]]; 00140 c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf); 00141 sResult.append(1, c1); 00142 } 00143 00144 if(++nPos < nLength) { 00145 c1 = sString[nPos]; 00146 if(cFillChar == c1) 00147 break; 00148 00149 c1 = (char) DecodeTable[(unsigned char)sString[nPos]]; 00150 c = ((c << 6) & 0xc0) | c1; 00151 sResult.append(1, c); 00152 } 00153 } 00154 00155 return sResult; 00156 } 00157 00158 #endif // B64_BASE64_H