00001
00122 #ifndef OC_CODER_H
00123 #define OC_CODER_H
00124
00125 #include <string>
00126 #include <algorithm>
00127 #include <vector>
00128
00129
00130 using namespace std;
00131
00132
00133 const size_t ENCODELength = 57;
00134 const size_t DECODELength = 76;
00135 const size_t REVARRAYSize = 126;
00136
00137
00138 #pragma pack(1)
00139 #ifdef IS_BIG_ENDIAN
00140 union b24bits
00141 {
00142 struct {
00143 unsigned int ch4:6;
00144 unsigned int ch3:6;
00145 unsigned int ch2:6;
00146 unsigned int ch1:6;
00147 } bit6Sequence;
00148 struct {
00149 unsigned char ch3;
00150 unsigned char ch2;
00151 unsigned char ch1;
00152 } byteSequence;
00153 };
00154 #else
00155 union b24bits
00156 {
00157 struct {
00158 unsigned int ch1:6;
00159 unsigned int ch2:6;
00160 unsigned int ch3:6;
00161 unsigned int ch4:6;
00162 } bit6Sequence;
00163 struct {
00164 unsigned char ch1;
00165 unsigned char ch2;
00166 unsigned char ch3;
00167 } byteSequence;
00168 };
00169 #endif
00170
00171 #pragma pack()
00172
00173 typedef vector< unsigned char > bins;
00174
00175 class ocCoder
00176 {
00177 private:
00178 string alphabet;
00179 bins ralphabet;
00180 bins bindata;
00181 string base64data;
00182 char base64pad;
00183 b24bits base64mask;
00184
00185 public:
00186 ocCoder()
00187
00188
00189
00190 :alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
00191 ,ralphabet(REVARRAYSize,'\0')
00192 ,bindata(ENCODELength,'\0')
00193 ,base64pad('=')
00194 {
00195
00196 ralphabet[65] = 0; ralphabet[66] = 1; ralphabet[67] = 2; ralphabet[68] = 3;
00197 ralphabet[69] = 4; ralphabet[70] = 5; ralphabet[71] = 6; ralphabet[72] = 7;
00198 ralphabet[73] = 8; ralphabet[74] = 9; ralphabet[75] = 10; ralphabet[76] = 11;
00199 ralphabet[77] = 12; ralphabet[78] = 13; ralphabet[79] = 14; ralphabet[80] = 15;
00200 ralphabet[81] = 16; ralphabet[82] = 17; ralphabet[83] = 18; ralphabet[84] = 19;
00201 ralphabet[85] = 20; ralphabet[86] = 21; ralphabet[87] = 22; ralphabet[88] = 23;
00202 ralphabet[89] = 24; ralphabet[90] = 25; ralphabet[97] = 26; ralphabet[98] = 27;
00203 ralphabet[99] = 28; ralphabet[100] = 29; ralphabet[101] = 30; ralphabet[102] = 31;
00204 ralphabet[103] = 32; ralphabet[104] = 33; ralphabet[105] = 34; ralphabet[106] = 35;
00205 ralphabet[107] = 36; ralphabet[108] = 37; ralphabet[109] = 38; ralphabet[110] = 39;
00206 ralphabet[111] = 40; ralphabet[112] = 41; ralphabet[113] = 42; ralphabet[114] = 43;
00207 ralphabet[115] = 44; ralphabet[116] = 45; ralphabet[117] = 46; ralphabet[118] = 47;
00208 ralphabet[119] = 48; ralphabet[120] = 49; ralphabet[121] = 50; ralphabet[122] = 51;
00209 ralphabet[48] = 52; ralphabet[49] = 53; ralphabet[50] = 54; ralphabet[51] = 55;
00210 ralphabet[52] = 56; ralphabet[53] = 57; ralphabet[54] = 58; ralphabet[55] = 59;
00211 ralphabet[56] = 60; ralphabet[57] = 61; ralphabet[43] = 62; ralphabet[47] = 63;
00212 }
00213
00214 virtual ~ocCoder()
00215 {;}
00216
00217
00218
00219
00220 string & base64encode( const unsigned char * input, size_t length )
00221 {
00222
00223 base64data = "";
00224 base64data.resize(DECODELength);
00225
00226
00227 if( length <= ENCODELength )
00228 {
00229 int idx,odx;
00230 for( idx=0,odx=0;
00231 input && idx < length;
00232 idx += 3, odx+=4 )
00233 {
00234
00235 memset( &base64mask, 0, 3 );
00236
00237
00238 base64mask.byteSequence.ch3 = input[idx];
00239 if( (idx+1) < length ) base64mask.byteSequence.ch2 = input[idx+1];
00240 if( (idx+2) < length ) base64mask.byteSequence.ch1 = input[idx+2];
00241
00242
00243 base64data[odx] = alphabet[base64mask.bit6Sequence.ch4];
00244 base64data[odx+1] = alphabet[base64mask.bit6Sequence.ch3];
00245
00246 if( (idx+1) < length ) base64data[odx+2] = alphabet[base64mask.bit6Sequence.ch2];
00247 else base64data[odx+2] = base64pad;
00248 if( (idx+2) < length ) base64data[odx+3] = alphabet[base64mask.bit6Sequence.ch1];
00249 else base64data[odx+3] = base64pad;
00250 }
00251 }
00252 return base64data;
00253 }
00254
00255 bins & base64decode ( string & encoded )
00256 {
00257 bindata.clear();
00258 int idx;
00259
00260 for( idx = 0; idx < encoded.length(); idx+=4 )
00261 {
00262
00263 memset( &base64mask, 0, 3 );
00264
00265
00266 base64mask.bit6Sequence.ch4 = ralphabet[encoded[idx]];
00267 base64mask.bit6Sequence.ch3 = ralphabet[encoded[idx+1]];
00268 if(encoded[idx+2] != base64pad) base64mask.bit6Sequence.ch2 = ralphabet[encoded[idx+2]];
00269 if(encoded[idx+3] != base64pad) base64mask.bit6Sequence.ch1 = ralphabet[encoded[idx+3]];
00270
00271
00272 bindata.push_back(base64mask.byteSequence.ch3);
00273 if(encoded[idx+2] != base64pad) bindata.push_back(base64mask.byteSequence.ch2);
00274 if(encoded[idx+3] != base64pad) bindata.push_back(base64mask.byteSequence.ch1);
00275 }
00276
00277
00278 return bindata;
00279 }
00280
00281 string & data( void )
00282 {
00283 return base64data;
00284 }
00285 };
00286
00287
00288 ostream & operator << ( ostream & outstream, bins & binary )
00289 {
00290 for( int i=0; i < binary.size(); i++ )
00291 {
00292 outstream.put( binary[i] );
00293 }
00294 return outstream;
00295 }
00296
00297 #endif