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