00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <stdlib.h>
00037
00038 #include "qmdcodec.h"
00039
00040 #define QMD5_S11 7
00041 #define QMD5_S12 12
00042 #define QMD5_S13 17
00043 #define QMD5_S14 22
00044 #define QMD5_S21 5
00045 #define QMD5_S22 9
00046 #define QMD5_S23 14
00047 #define QMD5_S24 20
00048 #define QMD5_S31 4
00049 #define QMD5_S32 11
00050 #define QMD5_S33 16
00051 #define QMD5_S34 23
00052 #define QMD5_S41 6
00053 #define QMD5_S42 10
00054 #define QMD5_S43 15
00055 #define QMD5_S44 21
00056
00057 const char QCodecs::Base64EncMap[64] =
00058 {
00059 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
00060 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
00061 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
00062 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
00063 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
00064 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
00065 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
00066 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
00067 };
00068
00069 const char QCodecs::Base64DecMap[128] =
00070 {
00071 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00072 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00073 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00076 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
00077 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
00078 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00079 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
00080 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
00081 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
00082 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
00083 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
00084 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
00085 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
00086 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
00087 };
00088
00089 const char QCodecs::UUEncMap[64] =
00090 {
00091 0x60, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
00092 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
00093 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
00094 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
00095 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
00096 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
00097 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
00098 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
00099 };
00100
00101 const char QCodecs::UUDecMap[128] =
00102 {
00103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00107 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
00108 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
00109 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
00110 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
00111 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
00112 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
00113 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
00114 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
00115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00119 };
00120
00121 const char QCodecs::hexChars[16] =
00122 {
00123 '0', '1', '2', '3', '4', '5', '6', '7',
00124 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
00125 };
00126
00127 const unsigned int QCodecs::maxQPLineLength = 70;
00128
00129
00130
00131
00132 static int rikFindChar(register const char * _s, const char c)
00133 {
00134 register const char * s = _s;
00135
00136 while (true)
00137 {
00138 if ((0 == *s) || (c == *s)) break; ++s;
00139 if ((0 == *s) || (c == *s)) break; ++s;
00140 if ((0 == *s) || (c == *s)) break; ++s;
00141 if ((0 == *s) || (c == *s)) break; ++s;
00142 }
00143
00144 return s - _s;
00145 }
00146
00147 QCString QCodecs::quotedPrintableEncode(const QByteArray& in, bool useCRLF)
00148 {
00149 QByteArray out;
00150 quotedPrintableEncode (in, out, useCRLF);
00151 return QCString (out.data(), out.size()+1);
00152 }
00153
00154 QCString QCodecs::quotedPrintableEncode(const QCString& str, bool useCRLF)
00155 {
00156 if (str.isEmpty())
00157 return "";
00158
00159 QByteArray in (str.length());
00160 memcpy (in.data(), str.data(), str.length());
00161 return quotedPrintableEncode(in, useCRLF);
00162 }
00163
00164 void QCodecs::quotedPrintableEncode(const QByteArray& in, QByteArray& out, bool useCRLF)
00165 {
00166 out.resize (0);
00167 if (in.isEmpty())
00168 return;
00169
00170 char *cursor;
00171 const char *data;
00172 unsigned int lineLength;
00173 unsigned int pos;
00174
00175 const unsigned int length = in.size();
00176 const unsigned int end = length - 1;
00177
00178
00179
00180
00181
00182
00183 out.resize ((length*12)/10);
00184 cursor = out.data();
00185 data = in.data();
00186 lineLength = 0;
00187 pos = 0;
00188
00189 for (unsigned int i = 0; i < length; i++)
00190 {
00191 unsigned char c (data[i]);
00192
00193
00194
00195 pos = cursor-out.data();
00196 if (out.size()-pos < 16) {
00197 out.resize(out.size()+4096);
00198 cursor = out.data()+pos;
00199 }
00200
00201
00202
00203 if ((c >= 33) && (c <= 126) && ('=' != c))
00204 {
00205 *cursor++ = c;
00206 ++lineLength;
00207 }
00208
00209
00210
00211 else if (' ' == c)
00212 {
00213 if
00214 (
00215 (i >= length)
00216 ||
00217 ((i < end) && ((useCRLF && ('\r' == data[i + 1]) && ('\n' == data[i + 2]))
00218 ||
00219 (!useCRLF && ('\n' == data[i + 1]))))
00220 )
00221 {
00222 *cursor++ = '=';
00223 *cursor++ = '2';
00224 *cursor++ = '0';
00225
00226 lineLength += 3;
00227 }
00228 else
00229 {
00230 *cursor++ = ' ';
00231 ++lineLength;
00232 }
00233 }
00234
00235 else if ((useCRLF && ('\r' == c) && (i < end) && ('\n' == data[i + 1])) ||
00236 (!useCRLF && ('\n' == c)))
00237 {
00238 lineLength = 0;
00239
00240 if (useCRLF) {
00241 *cursor++ = '\r';
00242 *cursor++ = '\n';
00243 ++i;
00244 } else {
00245 *cursor++ = '\n';
00246 }
00247 }
00248
00249
00250
00251 else
00252 {
00253 *cursor++ = '=';
00254 *cursor++ = hexChars[c / 16];
00255 *cursor++ = hexChars[c % 16];
00256
00257 lineLength += 3;
00258 }
00259
00260
00261
00262 if ((lineLength > maxQPLineLength) && (i < end))
00263 {
00264 if (useCRLF) {
00265 *cursor++ = '=';
00266 *cursor++ = '\r';
00267 *cursor++ = '\n';
00268 } else {
00269 *cursor++ = '=';
00270 *cursor++ = '\n';
00271 }
00272
00273 lineLength = 0;
00274 }
00275 }
00276
00277 out.truncate(cursor - out.data());
00278 }
00279
00280 QCString QCodecs::quotedPrintableDecode(const QByteArray & in)
00281 {
00282 QByteArray out;
00283 quotedPrintableDecode (in, out);
00284 return QCString (out.data(), out.size()+1);
00285 }
00286
00287 QCString QCodecs::quotedPrintableDecode(const QCString & str)
00288 {
00289 if (str.isEmpty())
00290 return "";
00291
00292 QByteArray in (str.length());
00293 memcpy (in.data(), str.data(), str.length());
00294 return quotedPrintableDecode (in);
00295 }
00296
00297 void QCodecs::quotedPrintableDecode(const QByteArray& in, QByteArray& out)
00298 {
00299
00300 out.resize (0);
00301 if (in.isEmpty())
00302 return;
00303
00304 char *cursor;
00305 const char *data;
00306 const unsigned int length = in.size();
00307
00308 data = in.data();
00309 out.resize (length);
00310 cursor = out.data();
00311
00312 for (unsigned int i = 0; i < length; i++)
00313 {
00314 char c(in.at(i));
00315
00316 if ('=' == c)
00317 {
00318 if (i < length - 2)
00319 {
00320 char c1 = in.at(i + 1);
00321 char c2 = in.at(i + 2);
00322
00323 if (('\n' == c1) || ('\r' == c1 && '\n' == c2))
00324 {
00325
00326 if ('\r' == c1)
00327 i += 2;
00328 else
00329 i += 1;
00330 }
00331 else
00332 {
00333
00334
00335 int hexChar0 = rikFindChar(hexChars, c1);
00336 int hexChar1 = rikFindChar(hexChars, c2);
00337
00338 if (hexChar0 < 16 && hexChar1 < 16)
00339 {
00340 *cursor++ = char((hexChar0 * 16) | hexChar1);
00341 i += 2;
00342 }
00343 }
00344 }
00345 }
00346 else
00347 {
00348 *cursor++ = c;
00349 }
00350 }
00351
00352 out.truncate(cursor - out.data());
00353 }
00354
00355 QCString QCodecs::base64Encode( const QCString& str, bool insertLFs )
00356 {
00357 if ( str.isEmpty() )
00358 return "";
00359
00360 QByteArray in (str.length());
00361 memcpy( in.data(), str.data(), str.length() );
00362 return base64Encode( in, insertLFs );
00363 }
00364
00365 QCString QCodecs::base64Encode( const QByteArray& in, bool insertLFs )
00366 {
00367 QByteArray out;
00368 base64Encode( in, out, insertLFs );
00369 return QCString( out.data(), out.size()+1 );
00370 }
00371
00372 void QCodecs::base64Encode( const QByteArray& in, QByteArray& out,
00373 bool insertLFs )
00374 {
00375
00376 out.resize (0);
00377 if ( in.isEmpty() )
00378 return;
00379
00380 unsigned int sidx = 0;
00381 unsigned int didx = 0;
00382 const char* data = in.data();
00383 const unsigned int len = in.size();
00384
00385 unsigned int out_len = ((len+2)/3)*4;
00386
00387
00388
00389
00390 insertLFs = (insertLFs && out_len > 76);
00391 if ( insertLFs )
00392 out_len += ((out_len-1)/76);
00393
00394 int count = 0;
00395 out.resize( out_len );
00396
00397
00398 if ( len > 1 )
00399 {
00400 while (sidx < len-2)
00401 {
00402 if ( insertLFs )
00403 {
00404 if ( count && (count%76) == 0 )
00405 out.data()[didx++] = '\n';
00406 count += 4;
00407 }
00408 out.data()[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
00409 out.data()[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
00410 (data[sidx] << 4) & 077];
00411 out.data()[didx++] = Base64EncMap[(data[sidx+2] >> 6) & 003 |
00412 (data[sidx+1] << 2) & 077];
00413 out.data()[didx++] = Base64EncMap[data[sidx+2] & 077];
00414 sidx += 3;
00415 }
00416 }
00417
00418 if (sidx < len)
00419 {
00420 if ( insertLFs && (count > 0) && (count%76) == 0 )
00421 out.data()[didx++] = '\n';
00422
00423 out.data()[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
00424 if (sidx < len-1)
00425 {
00426 out.data()[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
00427 (data[sidx] << 4) & 077];
00428 out.data()[didx++] = Base64EncMap[(data[sidx+1] << 2) & 077];
00429 }
00430 else
00431 {
00432 out.data()[didx++] = Base64EncMap[(data[sidx] << 4) & 077];
00433 }
00434 }
00435
00436
00437 while (didx < out.size())
00438 {
00439 out.data()[didx] = '=';
00440 didx++;
00441 }
00442 }
00443
00444 QCString QCodecs::base64Decode( const QCString& str )
00445 {
00446 if ( str.isEmpty() )
00447 return "";
00448
00449 QByteArray in( str.length() );
00450 memcpy( in.data(), str.data(), str.length() );
00451 return base64Decode( in );
00452 }
00453
00454 QCString QCodecs::base64Decode( const QByteArray& in )
00455 {
00456 QByteArray out;
00457 base64Decode( in, out );
00458 return QCString( out.data(), out.size()+1 );
00459 }
00460
00461 void QCodecs::base64Decode( const QByteArray& in, QByteArray& out )
00462 {
00463 out.resize(0);
00464 if ( in.isEmpty() )
00465 return;
00466
00467 unsigned int count = 0;
00468 unsigned int len = in.size(), tail = len;
00469 const char* data = in.data();
00470
00471
00472 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
00473 data[count] == '\t' || data[count] == ' ') )
00474 count++;
00475
00476 #ifdef _WIN32
00477 if ( strnicmp(data+count, "begin", 5) == 0 )
00478 #else
00479 if ( strncasecmp(data+count, "begin", 5) == 0 )
00480 #endif
00481 {
00482 count += 5;
00483 while ( count < len && data[count] != '\n' && data[count] != '\r' )
00484 count++;
00485
00486 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
00487 count ++;
00488
00489 data += count;
00490 tail = (len -= count);
00491 }
00492
00493
00494
00495 while ( data[tail-1] == '=' || data[tail-1] == '\n' ||
00496 data[tail-1] == '\r' )
00497 if ( data[--tail] != '=' ) len = tail;
00498
00499 unsigned int outIdx = 0;
00500 out.resize( (count=len) );
00501 for (unsigned int idx = 0; idx < count; idx++)
00502 {
00503
00504
00505 unsigned char ch = data[idx];
00506 if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||
00507 (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
00508 {
00509 out.data()[outIdx++] = Base64DecMap[ch];
00510 }
00511 else
00512 {
00513 len--;
00514 tail--;
00515 }
00516 }
00517
00518
00519
00520
00521 len = (tail>(len/4)) ? tail-(len/4) : 0;
00522 unsigned int sidx = 0, didx = 0;
00523 if ( len > 1 )
00524 {
00525 while (didx < len-2)
00526 {
00527 out.data()[didx] = (((out.at(sidx) << 2) & 255) | ((out.at(sidx+1) >> 4) & 003));
00528 out.data()[didx+1] = (((out.at(sidx+1) << 4) & 255) | ((out.at(sidx+2) >> 2) & 017));
00529 out.data()[didx+2] = (((out.at(sidx+2) << 6) & 255) | (out.at(sidx+3) & 077));
00530 sidx += 4;
00531 didx += 3;
00532 }
00533 }
00534
00535 if (didx < len)
00536 out.data()[didx] = (((out.at(sidx) << 2) & 255) | ((out.at(sidx+1) >> 4) & 003));
00537
00538 if (++didx < len )
00539 out.data()[didx] = (((out.at(sidx+1) << 4) & 255) | ((out.at(sidx+2) >> 2) & 017));
00540
00541
00542 if ( len == 0 || len < out.size() )
00543 out.resize(len);
00544 }
00545
00546 QCString QCodecs::uuencode( const QCString& str )
00547 {
00548 if ( str.isEmpty() )
00549 return "";
00550
00551 QByteArray in;
00552 in.resize( str.length() );
00553 memcpy( in.data(), str.data(), str.length() );
00554 return uuencode( in );
00555 }
00556
00557 QCString QCodecs::uuencode( const QByteArray& in )
00558 {
00559 QByteArray out;
00560 uuencode( in, out );
00561 return QCString( out.data(), out.size()+1 );
00562 }
00563
00564 void QCodecs::uuencode( const QByteArray& in, QByteArray& out )
00565 {
00566 out.resize( 0 );
00567 if (in.isEmpty() )
00568 return;
00569
00570 unsigned int sidx = 0;
00571 unsigned int didx = 0;
00572 unsigned int line_len = 45;
00573
00574 const char nl[] = "\n";
00575 const char* data = in.data();
00576 const unsigned int nl_len = strlen(nl);
00577 const unsigned int len = in.size();
00578
00579 out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );
00580
00581 while (sidx+line_len < len)
00582 {
00583
00584 out.data()[didx++] = UUEncMap[line_len];
00585
00586
00587 for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)
00588 {
00589 out.data()[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00590 out.data()[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00591 (data[sidx] << 4) & 077];
00592 out.data()[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
00593 (data[sidx+1] << 2) & 077];
00594 out.data()[didx++] = UUEncMap[data[sidx+2] & 077];
00595 }
00596
00597
00598
00599
00600 memcpy(out.data()+didx, nl, nl_len);
00601 didx += nl_len;
00602 }
00603
00604
00605 out.data()[didx++] = UUEncMap[len-sidx];
00606
00607 while (sidx+2 < len)
00608 {
00609 out.data()[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00610 out.data()[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00611 (data[sidx] << 4) & 077];
00612 out.data()[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
00613 (data[sidx+1] << 2) & 077];
00614 out.data()[didx++] = UUEncMap[data[sidx+2] & 077];
00615 sidx += 3;
00616 }
00617
00618 if (sidx < len-1)
00619 {
00620 out.data()[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00621 out.data()[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00622 (data[sidx] << 4) & 077];
00623 out.data()[didx++] = UUEncMap[(data[sidx+1] << 2) & 077];
00624 out.data()[didx++] = UUEncMap[0];
00625 }
00626 else if (sidx < len)
00627 {
00628 out.data()[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00629 out.data()[didx++] = UUEncMap[(data[sidx] << 4) & 077];
00630 out.data()[didx++] = UUEncMap[0];
00631 out.data()[didx++] = UUEncMap[0];
00632 }
00633
00634
00635 memcpy(out.data()+didx, nl, nl_len);
00636 didx += nl_len;
00637
00638
00639 if ( didx != out.size() )
00640 out.resize( 0 );
00641 }
00642
00643 QCString QCodecs::uudecode( const QCString& str )
00644 {
00645 if ( str.isEmpty() )
00646 return "";
00647
00648 QByteArray in;
00649 in.resize( str.length() );
00650 memcpy( in.data(), str.data(), str.length() );
00651 return uudecode( in );
00652 }
00653
00654 QCString QCodecs::uudecode( const QByteArray& in )
00655 {
00656 QByteArray out;
00657 uudecode( in, out );
00658 return QCString( out.data(), out.size()+1 );
00659 }
00660
00661 void QCodecs::uudecode( const QByteArray& in, QByteArray& out )
00662 {
00663 out.resize( 0 );
00664 if (in.isEmpty() )
00665 return;
00666
00667 unsigned int sidx = 0;
00668 unsigned int didx = 0;
00669 unsigned int len = in.size();
00670 unsigned int line_len, end;
00671 const char* data = in.data();
00672
00673
00674 unsigned int count = 0;
00675 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
00676 data[count] == '\t' || data[count] == ' ') )
00677 count ++;
00678
00679 bool hasLF = false;
00680
00681 #ifdef _WIN32
00682 if ( strnicmp( data+count, "begin", 5) == 0 )
00683 #else
00684 if ( strncasecmp( data+count, "begin", 5) == 0 )
00685 #endif
00686 {
00687 count += 5;
00688 while ( count < len && data[count] != '\n' && data[count] != '\r' )
00689 count ++;
00690
00691 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
00692 count ++;
00693
00694 data += count;
00695 len -= count;
00696 hasLF = true;
00697 }
00698
00699 out.resize( len/4*3 );
00700 while ( sidx < len )
00701 {
00702
00703 line_len = UUDecMap[ (unsigned char) data[sidx++]];
00704
00705 end = didx+line_len;
00706 char A, B, C, D;
00707 if (end > 2) {
00708 while (didx < end-2)
00709 {
00710 A = UUDecMap[(unsigned char) data[sidx]];
00711 B = UUDecMap[(unsigned char) data[sidx+1]];
00712 C = UUDecMap[(unsigned char) data[sidx+2]];
00713 D = UUDecMap[(unsigned char) data[sidx+3]];
00714 out.data()[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
00715 out.data()[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
00716 out.data()[didx++] = ( ((C << 6) & 255) | (D & 077) );
00717 sidx += 4;
00718 }
00719 }
00720
00721 if (didx < end)
00722 {
00723 A = UUDecMap[(unsigned char) data[sidx]];
00724 B = UUDecMap[(unsigned char) data[sidx+1]];
00725 out.data()[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
00726 }
00727
00728 if (didx < end)
00729 {
00730 B = UUDecMap[(unsigned char) data[sidx+1]];
00731 C = UUDecMap[(unsigned char) data[sidx+2]];
00732 out.data()[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
00733 }
00734
00735
00736 while (sidx < len && data[sidx] != '\n' && data[sidx] != '\r')
00737 sidx++;
00738
00739
00740 while (sidx < len && (data[sidx] == '\n' || data[sidx] == '\r'))
00741 sidx++;
00742
00743
00744 #ifdef _WIN32
00745 if ( hasLF && strnicmp( data+sidx, "end", 3) == 0 )
00746 #else
00747 if ( hasLF && strncasecmp( data+sidx, "end", 3) == 0 )
00748 #endif
00749 break;
00750 }
00751
00752 if ( didx < out.size() )
00753 out.resize( didx );
00754 }
00755
00756
00757 QMD5::QMD5()
00758 {
00759 init();
00760 }
00761
00762 QMD5::QMD5(const char *in, int len)
00763 {
00764 init();
00765 update(in, len);
00766 }
00767
00768 QMD5::QMD5(const QByteArray& in)
00769 {
00770 init();
00771 update( in );
00772 }
00773
00774 QMD5::QMD5(const QCString& in)
00775 {
00776 init();
00777 update( in );
00778 }
00779
00780 void QMD5::update(const QByteArray& in)
00781 {
00782 update(in.data(), int(in.size()));
00783 }
00784
00785 void QMD5::update(const QCString& in)
00786 {
00787 update(in.data(), int(in.length()));
00788 }
00789
00790 void QMD5::update(const unsigned char* in, int len)
00791 {
00792 if (len < 0)
00793 len = qstrlen(reinterpret_cast<const char*>(in));
00794
00795 if (!len)
00796 return;
00797
00798 if (m_finalized) {
00799 qWarning("QMD5::update called after state was finalized!");
00800 return;
00801 }
00802
00803 Q_UINT32 in_index;
00804 Q_UINT32 buffer_index;
00805 Q_UINT32 buffer_space;
00806 Q_UINT32 in_length = static_cast<Q_UINT32>( len );
00807
00808 buffer_index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3F);
00809
00810 if ( (m_count[0] += (in_length << 3))<(in_length << 3) )
00811 m_count[1]++;
00812
00813 m_count[1] += (in_length >> 29);
00814 buffer_space = 64 - buffer_index;
00815
00816 if (in_length >= buffer_space)
00817 {
00818 memcpy (m_buffer + buffer_index, in, buffer_space);
00819 transform (m_buffer);
00820
00821 for (in_index = buffer_space; in_index + 63 < in_length;
00822 in_index += 64)
00823 transform (reinterpret_cast<const unsigned char*>(in+in_index));
00824
00825 buffer_index = 0;
00826 }
00827 else
00828 in_index=0;
00829
00830 memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);
00831 }
00832
00833 bool QMD5::update(QIODevice& file)
00834 {
00835 char buffer[1024];
00836 int len;
00837
00838 while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
00839 update(buffer, len);
00840
00841 return file.atEnd();
00842 }
00843
00844 void QMD5::finalize ()
00845 {
00846 if (m_finalized) return;
00847
00848 Q_UINT8 bits[8];
00849 Q_UINT32 index, padLen;
00850 static unsigned char PADDING[64]=
00851 {
00852 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00853 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00854 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00855 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00856 };
00857
00858 encode (bits, m_count, 8);
00859
00860
00861
00862 index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3f);
00863 padLen = (index < 56) ? (56 - index) : (120 - index);
00864 update (reinterpret_cast<const char*>(PADDING), padLen);
00865
00866
00867 update (reinterpret_cast<const char*>(bits), 8);
00868
00869
00870 encode (m_digest, m_state, 16);
00871
00872
00873
00874 memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
00875
00876 m_finalized = true;
00877 }
00878
00879
00880 bool QMD5::verify( const QMD5::Digest& digest)
00881 {
00882 finalize();
00883 return (0 == memcmp(rawDigest(), digest, sizeof(QMD5::Digest)));
00884 }
00885
00886 bool QMD5::verify( const QCString& hexdigest)
00887 {
00888 finalize();
00889 return (0 == strcmp(hexDigest().data(), hexdigest));
00890 }
00891
00892 const QMD5::Digest& QMD5::rawDigest()
00893 {
00894 finalize();
00895 return m_digest;
00896 }
00897
00898 void QMD5::rawDigest( QMD5::Digest& bin )
00899 {
00900 finalize();
00901 memcpy( bin, m_digest, 16 );
00902 }
00903
00904
00905 QCString QMD5::hexDigest()
00906 {
00907 QCString s(33);
00908
00909 finalize();
00910 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
00911 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
00912 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
00913 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
00914
00915 return s;
00916 }
00917
00918 void QMD5::hexDigest(QCString& s)
00919 {
00920 finalize();
00921 s.resize(33);
00922 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
00923 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
00924 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
00925 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
00926 }
00927
00928 QCString QMD5::base64Digest()
00929 {
00930 QByteArray ba(16);
00931
00932 finalize();
00933 memcpy(ba.data(), m_digest, 16);
00934 return QCodecs::base64Encode(ba);
00935 }
00936
00937
00938 void QMD5::init()
00939 {
00940 d = 0;
00941 reset();
00942 }
00943
00944 void QMD5::reset()
00945 {
00946 m_finalized = false;
00947
00948 m_count[0] = 0;
00949 m_count[1] = 0;
00950
00951 m_state[0] = 0x67452301;
00952 m_state[1] = 0xefcdab89;
00953 m_state[2] = 0x98badcfe;
00954 m_state[3] = 0x10325476;
00955
00956 memset ( m_buffer, 0, sizeof(*m_buffer));
00957 memset ( m_digest, 0, sizeof(*m_digest));
00958 }
00959
00960 void QMD5::transform( const unsigned char block[64] )
00961 {
00962
00963 Q_UINT32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];
00964
00965 decode (x, block, 64);
00966
00967
00968 Q_ASSERT(!m_finalized);
00969
00970
00971 FF (a, b, c, d, x[ 0], QMD5_S11, 0xd76aa478);
00972 FF (d, a, b, c, x[ 1], QMD5_S12, 0xe8c7b756);
00973 FF (c, d, a, b, x[ 2], QMD5_S13, 0x242070db);
00974 FF (b, c, d, a, x[ 3], QMD5_S14, 0xc1bdceee);
00975 FF (a, b, c, d, x[ 4], QMD5_S11, 0xf57c0faf);
00976 FF (d, a, b, c, x[ 5], QMD5_S12, 0x4787c62a);
00977 FF (c, d, a, b, x[ 6], QMD5_S13, 0xa8304613);
00978 FF (b, c, d, a, x[ 7], QMD5_S14, 0xfd469501);
00979 FF (a, b, c, d, x[ 8], QMD5_S11, 0x698098d8);
00980 FF (d, a, b, c, x[ 9], QMD5_S12, 0x8b44f7af);
00981 FF (c, d, a, b, x[10], QMD5_S13, 0xffff5bb1);
00982 FF (b, c, d, a, x[11], QMD5_S14, 0x895cd7be);
00983 FF (a, b, c, d, x[12], QMD5_S11, 0x6b901122);
00984 FF (d, a, b, c, x[13], QMD5_S12, 0xfd987193);
00985 FF (c, d, a, b, x[14], QMD5_S13, 0xa679438e);
00986 FF (b, c, d, a, x[15], QMD5_S14, 0x49b40821);
00987
00988
00989 GG (a, b, c, d, x[ 1], QMD5_S21, 0xf61e2562);
00990 GG (d, a, b, c, x[ 6], QMD5_S22, 0xc040b340);
00991 GG (c, d, a, b, x[11], QMD5_S23, 0x265e5a51);
00992 GG (b, c, d, a, x[ 0], QMD5_S24, 0xe9b6c7aa);
00993 GG (a, b, c, d, x[ 5], QMD5_S21, 0xd62f105d);
00994 GG (d, a, b, c, x[10], QMD5_S22, 0x2441453);
00995 GG (c, d, a, b, x[15], QMD5_S23, 0xd8a1e681);
00996 GG (b, c, d, a, x[ 4], QMD5_S24, 0xe7d3fbc8);
00997 GG (a, b, c, d, x[ 9], QMD5_S21, 0x21e1cde6);
00998 GG (d, a, b, c, x[14], QMD5_S22, 0xc33707d6);
00999 GG (c, d, a, b, x[ 3], QMD5_S23, 0xf4d50d87);
01000 GG (b, c, d, a, x[ 8], QMD5_S24, 0x455a14ed);
01001 GG (a, b, c, d, x[13], QMD5_S21, 0xa9e3e905);
01002 GG (d, a, b, c, x[ 2], QMD5_S22, 0xfcefa3f8);
01003 GG (c, d, a, b, x[ 7], QMD5_S23, 0x676f02d9);
01004 GG (b, c, d, a, x[12], QMD5_S24, 0x8d2a4c8a);
01005
01006
01007 HH (a, b, c, d, x[ 5], QMD5_S31, 0xfffa3942);
01008 HH (d, a, b, c, x[ 8], QMD5_S32, 0x8771f681);
01009 HH (c, d, a, b, x[11], QMD5_S33, 0x6d9d6122);
01010 HH (b, c, d, a, x[14], QMD5_S34, 0xfde5380c);
01011 HH (a, b, c, d, x[ 1], QMD5_S31, 0xa4beea44);
01012 HH (d, a, b, c, x[ 4], QMD5_S32, 0x4bdecfa9);
01013 HH (c, d, a, b, x[ 7], QMD5_S33, 0xf6bb4b60);
01014 HH (b, c, d, a, x[10], QMD5_S34, 0xbebfbc70);
01015 HH (a, b, c, d, x[13], QMD5_S31, 0x289b7ec6);
01016 HH (d, a, b, c, x[ 0], QMD5_S32, 0xeaa127fa);
01017 HH (c, d, a, b, x[ 3], QMD5_S33, 0xd4ef3085);
01018 HH (b, c, d, a, x[ 6], QMD5_S34, 0x4881d05);
01019 HH (a, b, c, d, x[ 9], QMD5_S31, 0xd9d4d039);
01020 HH (d, a, b, c, x[12], QMD5_S32, 0xe6db99e5);
01021 HH (c, d, a, b, x[15], QMD5_S33, 0x1fa27cf8);
01022 HH (b, c, d, a, x[ 2], QMD5_S34, 0xc4ac5665);
01023
01024
01025 II (a, b, c, d, x[ 0], QMD5_S41, 0xf4292244);
01026 II (d, a, b, c, x[ 7], QMD5_S42, 0x432aff97);
01027 II (c, d, a, b, x[14], QMD5_S43, 0xab9423a7);
01028 II (b, c, d, a, x[ 5], QMD5_S44, 0xfc93a039);
01029 II (a, b, c, d, x[12], QMD5_S41, 0x655b59c3);
01030 II (d, a, b, c, x[ 3], QMD5_S42, 0x8f0ccc92);
01031 II (c, d, a, b, x[10], QMD5_S43, 0xffeff47d);
01032 II (b, c, d, a, x[ 1], QMD5_S44, 0x85845dd1);
01033 II (a, b, c, d, x[ 8], QMD5_S41, 0x6fa87e4f);
01034 II (d, a, b, c, x[15], QMD5_S42, 0xfe2ce6e0);
01035 II (c, d, a, b, x[ 6], QMD5_S43, 0xa3014314);
01036 II (b, c, d, a, x[13], QMD5_S44, 0x4e0811a1);
01037 II (a, b, c, d, x[ 4], QMD5_S41, 0xf7537e82);
01038 II (d, a, b, c, x[11], QMD5_S42, 0xbd3af235);
01039 II (c, d, a, b, x[ 2], QMD5_S43, 0x2ad7d2bb);
01040 II (b, c, d, a, x[ 9], QMD5_S44, 0xeb86d391);
01041
01042 m_state[0] += a;
01043 m_state[1] += b;
01044 m_state[2] += c;
01045 m_state[3] += d;
01046
01047 memset ( static_cast<void *>(x), 0, sizeof(x) );
01048 }
01049
01050 inline Q_UINT32 QMD5::rotate_left (Q_UINT32 x, Q_UINT32 n)
01051 {
01052 return (x << n) | (x >> (32-n)) ;
01053 }
01054
01055 inline Q_UINT32 QMD5::F (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01056 {
01057 return (x & y) | (~x & z);
01058 }
01059
01060 inline Q_UINT32 QMD5::G (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01061 {
01062 return (x & z) | (y & ~z);
01063 }
01064
01065 inline Q_UINT32 QMD5::H (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01066 {
01067 return x ^ y ^ z;
01068 }
01069
01070 inline Q_UINT32 QMD5::I (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01071 {
01072 return y ^ (x | ~z);
01073 }
01074
01075 void QMD5::FF ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01076 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
01077 {
01078 a += F(b, c, d) + x + ac;
01079 a = rotate_left (a, s) +b;
01080 }
01081
01082 void QMD5::GG ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01083 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac)
01084 {
01085 a += G(b, c, d) + x + ac;
01086 a = rotate_left (a, s) +b;
01087 }
01088
01089 void QMD5::HH ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01090 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
01091 {
01092 a += H(b, c, d) + x + ac;
01093 a = rotate_left (a, s) +b;
01094 }
01095
01096 void QMD5::II ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01097 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
01098 {
01099 a += I(b, c, d) + x + ac;
01100 a = rotate_left (a, s) +b;
01101 }
01102
01103
01104 void QMD5::encode ( unsigned char* output, Q_UINT32 *in, Q_UINT32 len )
01105 {
01106 #if !defined(WORDS_BIGENDIAN)
01107 memcpy(output, in, len);
01108
01109 #else
01110 Q_UINT32 i, j;
01111 for (i = 0, j = 0; j < len; i++, j += 4)
01112 {
01113 output[j] = static_cast<Q_UINT8>((in[i] & 0xff));
01114 output[j+1] = static_cast<Q_UINT8>(((in[i] >> 8) & 0xff));
01115 output[j+2] = static_cast<Q_UINT8>(((in[i] >> 16) & 0xff));
01116 output[j+3] = static_cast<Q_UINT8>(((in[i] >> 24) & 0xff));
01117 }
01118 #endif
01119 }
01120
01121
01122
01123 void QMD5::decode (Q_UINT32 *output, const unsigned char* in, Q_UINT32 len)
01124 {
01125 #if !defined(WORDS_BIGENDIAN)
01126 memcpy(output, in, len);
01127
01128 #else
01129 Q_UINT32 i, j;
01130 for (i = 0, j = 0; j < len; i++, j += 4)
01131 output[i] = static_cast<Q_UINT32>(in[j]) |
01132 (static_cast<Q_UINT32>(in[j+1]) << 8) |
01133 (static_cast<Q_UINT32>(in[j+2]) << 16) |
01134 (static_cast<Q_UINT32>(in[j+3]) << 24);
01135 #endif
01136 }