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