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
00035
00036
00037
00038 #include <config.h>
00039
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <stdlib.h>
00043
00044 #include <kswap.h>
00045 #include <kdebug.h>
00046 #include "kmdcodec.h"
00047
00048 #define KMD5_S11 7
00049 #define KMD5_S12 12
00050 #define KMD5_S13 17
00051 #define KMD5_S14 22
00052 #define KMD5_S21 5
00053 #define KMD5_S22 9
00054 #define KMD5_S23 14
00055 #define KMD5_S24 20
00056 #define KMD5_S31 4
00057 #define KMD5_S32 11
00058 #define KMD5_S33 16
00059 #define KMD5_S34 23
00060 #define KMD5_S41 6
00061 #define KMD5_S42 10
00062 #define KMD5_S43 15
00063 #define KMD5_S44 21
00064
00065 const char KCodecs::Base64EncMap[64] =
00066 {
00067 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
00068 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
00069 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
00070 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
00071 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
00072 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
00073 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
00074 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
00075 };
00076
00077 const char KCodecs::Base64DecMap[128] =
00078 {
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, 0x00, 0x00, 0x00, 0x00, 0x00,
00084 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
00085 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
00086 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00087 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
00088 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
00089 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
00090 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
00091 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
00092 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
00093 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
00094 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
00095 };
00096
00097 const char KCodecs::UUEncMap[64] =
00098 {
00099 0x60, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
00100 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
00101 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
00102 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
00103 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
00104 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
00105 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
00106 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
00107 };
00108
00109 const char KCodecs::UUDecMap[128] =
00110 {
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00115 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
00116 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
00117 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
00118 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
00119 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
00120 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
00121 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
00122 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00127 };
00128
00129 const char KCodecs::hexChars[16] =
00130 {
00131 '0', '1', '2', '3', '4', '5', '6', '7',
00132 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
00133 };
00134
00135 const unsigned int KCodecs::maxQPLineLength = 70;
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 QCString KCodecs::quotedPrintableEncode(const QByteArray& in, bool useCRLF)
00156 {
00157 QByteArray out;
00158 quotedPrintableEncode (in, out, useCRLF);
00159 return QCString (out.data(), out.size()+1);
00160 }
00161
00162 QCString KCodecs::quotedPrintableEncode(const QCString& str, bool useCRLF)
00163 {
00164 if (str.isEmpty())
00165 return "";
00166
00167 QByteArray in (str.length());
00168 memcpy (in.data(), str.data(), str.length());
00169 return quotedPrintableEncode(in, useCRLF);
00170 }
00171
00172 void KCodecs::quotedPrintableEncode(const QByteArray& in, QByteArray& out, bool useCRLF)
00173 {
00174 out.resize (0);
00175 if (in.isEmpty())
00176 return;
00177
00178 char *cursor;
00179 const char *data;
00180 unsigned int lineLength;
00181 unsigned int pos;
00182
00183 const unsigned int length = in.size();
00184 const unsigned int end = length - 1;
00185
00186
00187
00188
00189
00190
00191 out.resize ((length*12)/10);
00192 cursor = out.data();
00193 data = in.data();
00194 lineLength = 0;
00195 pos = 0;
00196
00197 for (unsigned int i = 0; i < length; i++)
00198 {
00199 unsigned char c (data[i]);
00200
00201
00202
00203 pos = cursor-out.data();
00204 if (out.size()-pos < 16) {
00205 out.resize(out.size()+4096);
00206 cursor = out.data()+pos;
00207 }
00208
00209
00210
00211 if ((c >= 33) && (c <= 126) && ('=' != c))
00212 {
00213 *cursor++ = c;
00214 ++lineLength;
00215 }
00216
00217
00218
00219 else if (' ' == c)
00220 {
00221 if
00222 (
00223 (i >= length)
00224 ||
00225 ((i < end) && ((useCRLF && ('\r' == data[i + 1]) && ('\n' == data[i + 2]))
00226 ||
00227 (!useCRLF && ('\n' == data[i + 1]))))
00228 )
00229 {
00230 *cursor++ = '=';
00231 *cursor++ = '2';
00232 *cursor++ = '0';
00233
00234 lineLength += 3;
00235 }
00236 else
00237 {
00238 *cursor++ = ' ';
00239 ++lineLength;
00240 }
00241 }
00242
00243 else if ((useCRLF && ('\r' == c) && (i < end) && ('\n' == data[i + 1])) ||
00244 (!useCRLF && ('\n' == c)))
00245 {
00246 lineLength = 0;
00247
00248 if (useCRLF) {
00249 *cursor++ = '\r';
00250 *cursor++ = '\n';
00251 ++i;
00252 } else {
00253 *cursor++ = '\n';
00254 }
00255 }
00256
00257
00258
00259 else
00260 {
00261 *cursor++ = '=';
00262 *cursor++ = hexChars[c / 16];
00263 *cursor++ = hexChars[c % 16];
00264
00265 lineLength += 3;
00266 }
00267
00268
00269
00270 if ((lineLength > maxQPLineLength) && (i < end))
00271 {
00272 if (useCRLF) {
00273 *cursor++ = '=';
00274 *cursor++ = '\r';
00275 *cursor++ = '\n';
00276 } else {
00277 *cursor++ = '=';
00278 *cursor++ = '\n';
00279 }
00280
00281 lineLength = 0;
00282 }
00283 }
00284
00285 out.truncate(cursor - out.data());
00286 }
00287
00288 QCString KCodecs::quotedPrintableDecode(const QByteArray & in)
00289 {
00290 QByteArray out;
00291 quotedPrintableDecode (in, out);
00292 return QCString (out.data(), out.size()+1);
00293 }
00294
00295 QCString KCodecs::quotedPrintableDecode(const QCString & str)
00296 {
00297 if (str.isEmpty())
00298 return "";
00299
00300 QByteArray in (str.length());
00301 memcpy (in.data(), str.data(), str.length());
00302 return quotedPrintableDecode (in);
00303 }
00304
00305 void KCodecs::quotedPrintableDecode(const QByteArray& in, QByteArray& out)
00306 {
00307
00308 out.resize (0);
00309 if (in.isEmpty())
00310 return;
00311
00312 char *cursor;
00313 const char *data;
00314 const unsigned int length = in.size();
00315
00316 data = in.data();
00317 out.resize (length);
00318 cursor = out.data();
00319
00320 for (unsigned int i = 0; i < length; i++)
00321 {
00322 char c(in[i]);
00323
00324 if ('=' == c)
00325 {
00326 if (i < length - 2)
00327 {
00328 char c1 = in[i + 1];
00329 char c2 = in[i + 2];
00330
00331 if (('\n' == c1) || ('\r' == c1 && '\n' == c2))
00332 {
00333
00334 if ('\r' == c1)
00335 i += 2;
00336 else
00337 i += 1;
00338 }
00339 else
00340 {
00341
00342
00343 int hexChar0 = rikFindChar(hexChars, c1);
00344 int hexChar1 = rikFindChar(hexChars, c2);
00345
00346 if (hexChar0 < 16 && hexChar1 < 16)
00347 {
00348 *cursor++ = char((hexChar0 * 16) | hexChar1);
00349 i += 2;
00350 }
00351 }
00352 }
00353 }
00354 else
00355 {
00356 *cursor++ = c;
00357 }
00358 }
00359
00360 out.truncate(cursor - out.data());
00361 }
00362
00363 QCString KCodecs::base64Encode( const QCString& str, bool insertLFs )
00364 {
00365 if ( str.isEmpty() )
00366 return "";
00367
00368 QByteArray in (str.length());
00369 memcpy( in.data(), str.data(), str.length() );
00370 return base64Encode( in, insertLFs );
00371 }
00372
00373 QCString KCodecs::base64Encode( const QByteArray& in, bool insertLFs )
00374 {
00375 QByteArray out;
00376 base64Encode( in, out, insertLFs );
00377 return QCString( out.data(), out.size()+1 );
00378 }
00379
00380 void KCodecs::base64Encode( const QByteArray& in, QByteArray& out,
00381 bool insertLFs )
00382 {
00383
00384 out.resize (0);
00385 if ( in.isEmpty() )
00386 return;
00387
00388 unsigned int sidx = 0;
00389 unsigned int didx = 0;
00390 const char* data = in.data();
00391 const unsigned int len = in.size();
00392
00393 unsigned int out_len = ((len+2)/3)*4;
00394
00395
00396
00397
00398 insertLFs = (insertLFs && out_len > 76);
00399 if ( insertLFs )
00400 out_len += ((out_len-1)/76);
00401
00402 int count = 0;
00403 out.resize( out_len );
00404
00405
00406 if ( len > 1 )
00407 {
00408 while (sidx < len-2)
00409 {
00410 if ( insertLFs )
00411 {
00412 if ( count && (count%76) == 0 )
00413 out[didx++] = '\n';
00414 count += 4;
00415 }
00416 out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
00417 out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
00418 (data[sidx] << 4) & 077];
00419 out[didx++] = Base64EncMap[(data[sidx+2] >> 6) & 003 |
00420 (data[sidx+1] << 2) & 077];
00421 out[didx++] = Base64EncMap[data[sidx+2] & 077];
00422 sidx += 3;
00423 }
00424 }
00425
00426 if (sidx < len)
00427 {
00428 if ( insertLFs && (count > 0) && (count%76) == 0 )
00429 out[didx++] = '\n';
00430
00431 out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
00432 if (sidx < len-1)
00433 {
00434 out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
00435 (data[sidx] << 4) & 077];
00436 out[didx++] = Base64EncMap[(data[sidx+1] << 2) & 077];
00437 }
00438 else
00439 {
00440 out[didx++] = Base64EncMap[(data[sidx] << 4) & 077];
00441 }
00442 }
00443
00444
00445 while (didx < out.size())
00446 {
00447 out[didx] = '=';
00448 didx++;
00449 }
00450 }
00451
00452 QCString KCodecs::base64Decode( const QCString& str )
00453 {
00454 if ( str.isEmpty() )
00455 return "";
00456
00457 QByteArray in( str.length() );
00458 memcpy( in.data(), str.data(), str.length() );
00459 return base64Decode( in );
00460 }
00461
00462 QCString KCodecs::base64Decode( const QByteArray& in )
00463 {
00464 QByteArray out;
00465 base64Decode( in, out );
00466 return QCString( out.data(), out.size()+1 );
00467 }
00468
00469 void KCodecs::base64Decode( const QByteArray& in, QByteArray& out )
00470 {
00471 out.resize(0);
00472 if ( in.isEmpty() )
00473 return;
00474
00475 unsigned int count = 0;
00476 unsigned int len = in.size(), tail = len;
00477 const char* data = in.data();
00478
00479
00480 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
00481 data[count] == '\t' || data[count] == ' ') )
00482 count++;
00483
00484 if ( strncasecmp(data+count, "begin", 5) == 0 )
00485 {
00486 count += 5;
00487 while ( count < len && data[count] != '\n' && data[count] != '\r' )
00488 count++;
00489
00490 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
00491 count ++;
00492
00493 data += count;
00494 tail = (len -= count);
00495 }
00496
00497
00498
00499 while ( data[tail-1] == '=' || data[tail-1] == '\n' ||
00500 data[tail-1] == '\r' )
00501 if ( data[--tail] != '=' ) len = tail;
00502
00503 unsigned int outIdx = 0;
00504 out.resize( (count=len) );
00505 for (unsigned int idx = 0; idx < count; idx++)
00506 {
00507
00508
00509 unsigned char ch = data[idx];
00510 if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||
00511 (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
00512 {
00513 out[outIdx++] = Base64DecMap[ch];
00514 }
00515 else
00516 {
00517 len--;
00518 tail--;
00519 }
00520 }
00521
00522
00523
00524
00525 len = (tail>(len/4)) ? tail-(len/4) : 0;
00526 unsigned int sidx = 0, didx = 0;
00527 if ( len > 1 )
00528 {
00529 while (didx < len-2)
00530 {
00531 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
00532 out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
00533 out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077));
00534 sidx += 4;
00535 didx += 3;
00536 }
00537 }
00538
00539 if (didx < len)
00540 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
00541
00542 if (++didx < len )
00543 out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
00544
00545
00546 if ( len == 0 || len < out.size() )
00547 out.resize(len);
00548 }
00549
00550 QCString KCodecs::uuencode( const QCString& str )
00551 {
00552 if ( str.isEmpty() )
00553 return "";
00554
00555 QByteArray in;
00556 in.resize( str.length() );
00557 memcpy( in.data(), str.data(), str.length() );
00558 return uuencode( in );
00559 }
00560
00561 QCString KCodecs::uuencode( const QByteArray& in )
00562 {
00563 QByteArray out;
00564 uuencode( in, out );
00565 return QCString( out.data(), out.size()+1 );
00566 }
00567
00568 void KCodecs::uuencode( const QByteArray& in, QByteArray& out )
00569 {
00570 out.resize( 0 );
00571 if( in.isEmpty() )
00572 return;
00573
00574 unsigned int sidx = 0;
00575 unsigned int didx = 0;
00576 unsigned int line_len = 45;
00577
00578 const char nl[] = "\n";
00579 const char* data = in.data();
00580 const unsigned int nl_len = strlen(nl);
00581 const unsigned int len = in.size();
00582
00583 out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );
00584
00585 while (sidx+line_len < len)
00586 {
00587
00588 out[didx++] = UUEncMap[line_len];
00589
00590
00591 for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)
00592 {
00593 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00594 out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00595 (data[sidx] << 4) & 077];
00596 out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
00597 (data[sidx+1] << 2) & 077];
00598 out[didx++] = UUEncMap[data[sidx+2] & 077];
00599 }
00600
00601
00602
00603
00604 memcpy(out.data()+didx, nl, nl_len);
00605 didx += nl_len;
00606 }
00607
00608
00609 out[didx++] = UUEncMap[len-sidx];
00610
00611 while (sidx+2 < len)
00612 {
00613 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00614 out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00615 (data[sidx] << 4) & 077];
00616 out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
00617 (data[sidx+1] << 2) & 077];
00618 out[didx++] = UUEncMap[data[sidx+2] & 077];
00619 sidx += 3;
00620 }
00621
00622 if (sidx < len-1)
00623 {
00624 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00625 out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00626 (data[sidx] << 4) & 077];
00627 out[didx++] = UUEncMap[(data[sidx+1] << 2) & 077];
00628 out[didx++] = UUEncMap[0];
00629 }
00630 else if (sidx < len)
00631 {
00632 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00633 out[didx++] = UUEncMap[(data[sidx] << 4) & 077];
00634 out[didx++] = UUEncMap[0];
00635 out[didx++] = UUEncMap[0];
00636 }
00637
00638
00639 memcpy(out.data()+didx, nl, nl_len);
00640 didx += nl_len;
00641
00642
00643 if ( didx != out.size() )
00644 out.resize( 0 );
00645 }
00646
00647 QCString KCodecs::uudecode( const QCString& str )
00648 {
00649 if ( str.isEmpty() )
00650 return "";
00651
00652 QByteArray in;
00653 in.resize( str.length() );
00654 memcpy( in.data(), str.data(), str.length() );
00655 return uudecode( in );
00656 }
00657
00658 QCString KCodecs::uudecode( const QByteArray& in )
00659 {
00660 QByteArray out;
00661 uudecode( in, out );
00662 return QCString( out.data(), out.size()+1 );
00663 }
00664
00665 void KCodecs::uudecode( const QByteArray& in, QByteArray& out )
00666 {
00667 out.resize( 0 );
00668 if( in.isEmpty() )
00669 return;
00670
00671 unsigned int sidx = 0;
00672 unsigned int didx = 0;
00673 unsigned int len = in.size();
00674 unsigned int line_len, end;
00675 const char* data = in.data();
00676
00677
00678 unsigned int count = 0;
00679 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
00680 data[count] == '\t' || data[count] == ' ') )
00681 count ++;
00682
00683 bool hasLF = false;
00684 if ( strncasecmp( data+count, "begin", 5) == 0 )
00685 {
00686 count += 5;
00687 while ( count < len && data[count] != '\n' && data[count] != '\r' )
00688 count ++;
00689
00690 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
00691 count ++;
00692
00693 data += count;
00694 len -= count;
00695 hasLF = true;
00696 }
00697
00698 out.resize( len/4*3 );
00699 while ( sidx < len )
00700 {
00701
00702 line_len = UUDecMap[ (unsigned char) data[sidx++]];
00703
00704 end = didx+line_len;
00705 char A, B, C, D;
00706 if (end > 2) {
00707 while (didx < end-2)
00708 {
00709 A = UUDecMap[(unsigned char) data[sidx]];
00710 B = UUDecMap[(unsigned char) data[sidx+1]];
00711 C = UUDecMap[(unsigned char) data[sidx+2]];
00712 D = UUDecMap[(unsigned char) data[sidx+3]];
00713 out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
00714 out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
00715 out[didx++] = ( ((C << 6) & 255) | (D & 077) );
00716 sidx += 4;
00717 }
00718 }
00719
00720 if (didx < end)
00721 {
00722 A = UUDecMap[(unsigned char) data[sidx]];
00723 B = UUDecMap[(unsigned char) data[sidx+1]];
00724 out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
00725 }
00726
00727 if (didx < end)
00728 {
00729 B = UUDecMap[(unsigned char) data[sidx+1]];
00730 C = UUDecMap[(unsigned char) data[sidx+2]];
00731 out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
00732 }
00733
00734
00735 while (sidx < len && data[sidx] != '\n' && data[sidx] != '\r')
00736 sidx++;
00737
00738
00739 while (sidx < len && (data[sidx] == '\n' || data[sidx] == '\r'))
00740 sidx++;
00741
00742
00743 if ( hasLF && strncasecmp( data+sidx, "end", 3) == 0 )
00744 break;
00745 }
00746
00747 if ( didx < out.size() )
00748 out.resize( didx );
00749 }
00750
00751
00752 KMD5::KMD5()
00753 {
00754 init();
00755 }
00756
00757 KMD5::KMD5(const char *in, int len)
00758 {
00759 init();
00760 update(in, len);
00761 }
00762
00763 KMD5::KMD5(const QByteArray& in)
00764 {
00765 init();
00766 update( in );
00767 }
00768
00769 KMD5::KMD5(const QCString& in)
00770 {
00771 init();
00772 update( in );
00773 }
00774
00775 void KMD5::update(const QByteArray& in)
00776 {
00777 update(in.data(), int(in.size()));
00778 }
00779
00780 void KMD5::update(const QCString& in)
00781 {
00782 update(in.data(), int(in.length()));
00783 }
00784
00785 void KMD5::update(const unsigned char* in, int len)
00786 {
00787 if (len < 0)
00788 len = qstrlen(reinterpret_cast<const char*>(in));
00789
00790 if (!len)
00791 return;
00792
00793 if (m_finalized) {
00794 kdWarning() << "KMD5::update called after state was finalized!" << endl;
00795 return;
00796 }
00797
00798 Q_UINT32 in_index;
00799 Q_UINT32 buffer_index;
00800 Q_UINT32 buffer_space;
00801 Q_UINT32 in_length = static_cast<Q_UINT32>( len );
00802
00803 buffer_index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3F);
00804
00805 if ( (m_count[0] += (in_length << 3))<(in_length << 3) )
00806 m_count[1]++;
00807
00808 m_count[1] += (in_length >> 29);
00809 buffer_space = 64 - buffer_index;
00810
00811 if (in_length >= buffer_space)
00812 {
00813 memcpy (m_buffer + buffer_index, in, buffer_space);
00814 transform (m_buffer);
00815
00816 for (in_index = buffer_space; in_index + 63 < in_length;
00817 in_index += 64)
00818 transform (reinterpret_cast<const unsigned char*>(in+in_index));
00819
00820 buffer_index = 0;
00821 }
00822 else
00823 in_index=0;
00824
00825 memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);
00826 }
00827
00828 bool KMD5::update(QIODevice& file)
00829 {
00830 char buffer[1024];
00831 int len;
00832
00833 while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
00834 update(buffer, len);
00835
00836 return file.atEnd();
00837 }
00838
00839 void KMD5::finalize ()
00840 {
00841 if (m_finalized) return;
00842
00843 Q_UINT8 bits[8];
00844 Q_UINT32 index, padLen;
00845 static const unsigned char PADDING[64]=
00846 {
00847 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00848 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00849 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00850 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00851 };
00852
00853 encode (bits, m_count, 8);
00854
00855
00856
00857 index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3f);
00858 padLen = (index < 56) ? (56 - index) : (120 - index);
00859 update (reinterpret_cast<const char*>(PADDING), padLen);
00860
00861
00862 update (reinterpret_cast<const char*>(bits), 8);
00863
00864
00865 encode (m_digest, m_state, 16);
00866
00867
00868
00869 memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
00870
00871 m_finalized = true;
00872 }
00873
00874
00875 bool KMD5::verify( const KMD5::Digest& digest)
00876 {
00877 finalize();
00878 return (0 == memcmp(rawDigest(), digest, sizeof(KMD5::Digest)));
00879 }
00880
00881 bool KMD5::verify( const QCString& hexdigest)
00882 {
00883 finalize();
00884 return (0 == strcmp(hexDigest().data(), hexdigest));
00885 }
00886
00887 const KMD5::Digest& KMD5::rawDigest()
00888 {
00889 finalize();
00890 return m_digest;
00891 }
00892
00893 void KMD5::rawDigest( KMD5::Digest& bin )
00894 {
00895 finalize();
00896 memcpy( bin, m_digest, 16 );
00897 }
00898
00899
00900 QCString KMD5::hexDigest()
00901 {
00902 QCString s(33);
00903
00904 finalize();
00905 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
00906 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
00907 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
00908 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
00909
00910 return s;
00911 }
00912
00913 void KMD5::hexDigest(QCString& s)
00914 {
00915 finalize();
00916 s.resize(33);
00917 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
00918 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
00919 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
00920 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
00921 }
00922
00923 QCString KMD5::base64Digest()
00924 {
00925 QByteArray ba(16);
00926
00927 finalize();
00928 memcpy(ba.data(), m_digest, 16);
00929 return KCodecs::base64Encode(ba);
00930 }
00931
00932
00933 void KMD5::init()
00934 {
00935 d = 0;
00936 reset();
00937 }
00938
00939 void KMD5::reset()
00940 {
00941 m_finalized = false;
00942
00943 m_count[0] = 0;
00944 m_count[1] = 0;
00945
00946 m_state[0] = 0x67452301;
00947 m_state[1] = 0xefcdab89;
00948 m_state[2] = 0x98badcfe;
00949 m_state[3] = 0x10325476;
00950
00951 memset ( m_buffer, 0, sizeof(*m_buffer));
00952 memset ( m_digest, 0, sizeof(*m_digest));
00953 }
00954
00955 void KMD5::transform( const unsigned char block[64] )
00956 {
00957
00958 Q_UINT32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];
00959
00960 decode (x, block, 64);
00961
00962
00963 Q_ASSERT(!m_finalized);
00964
00965
00966 FF (a, b, c, d, x[ 0], KMD5_S11, 0xd76aa478);
00967 FF (d, a, b, c, x[ 1], KMD5_S12, 0xe8c7b756);
00968 FF (c, d, a, b, x[ 2], KMD5_S13, 0x242070db);
00969 FF (b, c, d, a, x[ 3], KMD5_S14, 0xc1bdceee);
00970 FF (a, b, c, d, x[ 4], KMD5_S11, 0xf57c0faf);
00971 FF (d, a, b, c, x[ 5], KMD5_S12, 0x4787c62a);
00972 FF (c, d, a, b, x[ 6], KMD5_S13, 0xa8304613);
00973 FF (b, c, d, a, x[ 7], KMD5_S14, 0xfd469501);
00974 FF (a, b, c, d, x[ 8], KMD5_S11, 0x698098d8);
00975 FF (d, a, b, c, x[ 9], KMD5_S12, 0x8b44f7af);
00976 FF (c, d, a, b, x[10], KMD5_S13, 0xffff5bb1);
00977 FF (b, c, d, a, x[11], KMD5_S14, 0x895cd7be);
00978 FF (a, b, c, d, x[12], KMD5_S11, 0x6b901122);
00979 FF (d, a, b, c, x[13], KMD5_S12, 0xfd987193);
00980 FF (c, d, a, b, x[14], KMD5_S13, 0xa679438e);
00981 FF (b, c, d, a, x[15], KMD5_S14, 0x49b40821);
00982
00983
00984 GG (a, b, c, d, x[ 1], KMD5_S21, 0xf61e2562);
00985 GG (d, a, b, c, x[ 6], KMD5_S22, 0xc040b340);
00986 GG (c, d, a, b, x[11], KMD5_S23, 0x265e5a51);
00987 GG (b, c, d, a, x[ 0], KMD5_S24, 0xe9b6c7aa);
00988 GG (a, b, c, d, x[ 5], KMD5_S21, 0xd62f105d);
00989 GG (d, a, b, c, x[10], KMD5_S22, 0x2441453);
00990 GG (c, d, a, b, x[15], KMD5_S23, 0xd8a1e681);
00991 GG (b, c, d, a, x[ 4], KMD5_S24, 0xe7d3fbc8);
00992 GG (a, b, c, d, x[ 9], KMD5_S21, 0x21e1cde6);
00993 GG (d, a, b, c, x[14], KMD5_S22, 0xc33707d6);
00994 GG (c, d, a, b, x[ 3], KMD5_S23, 0xf4d50d87);
00995 GG (b, c, d, a, x[ 8], KMD5_S24, 0x455a14ed);
00996 GG (a, b, c, d, x[13], KMD5_S21, 0xa9e3e905);
00997 GG (d, a, b, c, x[ 2], KMD5_S22, 0xfcefa3f8);
00998 GG (c, d, a, b, x[ 7], KMD5_S23, 0x676f02d9);
00999 GG (b, c, d, a, x[12], KMD5_S24, 0x8d2a4c8a);
01000
01001
01002 HH (a, b, c, d, x[ 5], KMD5_S31, 0xfffa3942);
01003 HH (d, a, b, c, x[ 8], KMD5_S32, 0x8771f681);
01004 HH (c, d, a, b, x[11], KMD5_S33, 0x6d9d6122);
01005 HH (b, c, d, a, x[14], KMD5_S34, 0xfde5380c);
01006 HH (a, b, c, d, x[ 1], KMD5_S31, 0xa4beea44);
01007 HH (d, a, b, c, x[ 4], KMD5_S32, 0x4bdecfa9);
01008 HH (c, d, a, b, x[ 7], KMD5_S33, 0xf6bb4b60);
01009 HH (b, c, d, a, x[10], KMD5_S34, 0xbebfbc70);
01010 HH (a, b, c, d, x[13], KMD5_S31, 0x289b7ec6);
01011 HH (d, a, b, c, x[ 0], KMD5_S32, 0xeaa127fa);
01012 HH (c, d, a, b, x[ 3], KMD5_S33, 0xd4ef3085);
01013 HH (b, c, d, a, x[ 6], KMD5_S34, 0x4881d05);
01014 HH (a, b, c, d, x[ 9], KMD5_S31, 0xd9d4d039);
01015 HH (d, a, b, c, x[12], KMD5_S32, 0xe6db99e5);
01016 HH (c, d, a, b, x[15], KMD5_S33, 0x1fa27cf8);
01017 HH (b, c, d, a, x[ 2], KMD5_S34, 0xc4ac5665);
01018
01019
01020 II (a, b, c, d, x[ 0], KMD5_S41, 0xf4292244);
01021 II (d, a, b, c, x[ 7], KMD5_S42, 0x432aff97);
01022 II (c, d, a, b, x[14], KMD5_S43, 0xab9423a7);
01023 II (b, c, d, a, x[ 5], KMD5_S44, 0xfc93a039);
01024 II (a, b, c, d, x[12], KMD5_S41, 0x655b59c3);
01025 II (d, a, b, c, x[ 3], KMD5_S42, 0x8f0ccc92);
01026 II (c, d, a, b, x[10], KMD5_S43, 0xffeff47d);
01027 II (b, c, d, a, x[ 1], KMD5_S44, 0x85845dd1);
01028 II (a, b, c, d, x[ 8], KMD5_S41, 0x6fa87e4f);
01029 II (d, a, b, c, x[15], KMD5_S42, 0xfe2ce6e0);
01030 II (c, d, a, b, x[ 6], KMD5_S43, 0xa3014314);
01031 II (b, c, d, a, x[13], KMD5_S44, 0x4e0811a1);
01032 II (a, b, c, d, x[ 4], KMD5_S41, 0xf7537e82);
01033 II (d, a, b, c, x[11], KMD5_S42, 0xbd3af235);
01034 II (c, d, a, b, x[ 2], KMD5_S43, 0x2ad7d2bb);
01035 II (b, c, d, a, x[ 9], KMD5_S44, 0xeb86d391);
01036
01037 m_state[0] += a;
01038 m_state[1] += b;
01039 m_state[2] += c;
01040 m_state[3] += d;
01041
01042 memset ( static_cast<void *>(x), 0, sizeof(x) );
01043 }
01044
01045 inline Q_UINT32 KMD5::rotate_left (Q_UINT32 x, Q_UINT32 n)
01046 {
01047 return (x << n) | (x >> (32-n)) ;
01048 }
01049
01050 inline Q_UINT32 KMD5::F (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01051 {
01052 return (x & y) | (~x & z);
01053 }
01054
01055 inline Q_UINT32 KMD5::G (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01056 {
01057 return (x & z) | (y & ~z);
01058 }
01059
01060 inline Q_UINT32 KMD5::H (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01061 {
01062 return x ^ y ^ z;
01063 }
01064
01065 inline Q_UINT32 KMD5::I (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01066 {
01067 return y ^ (x | ~z);
01068 }
01069
01070 void KMD5::FF ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01071 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
01072 {
01073 a += F(b, c, d) + x + ac;
01074 a = rotate_left (a, s) +b;
01075 }
01076
01077 void KMD5::GG ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01078 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac)
01079 {
01080 a += G(b, c, d) + x + ac;
01081 a = rotate_left (a, s) +b;
01082 }
01083
01084 void KMD5::HH ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01085 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
01086 {
01087 a += H(b, c, d) + x + ac;
01088 a = rotate_left (a, s) +b;
01089 }
01090
01091 void KMD5::II ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01092 Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
01093 {
01094 a += I(b, c, d) + x + ac;
01095 a = rotate_left (a, s) +b;
01096 }
01097
01098
01099 void KMD5::encode ( unsigned char* output, Q_UINT32 *in, Q_UINT32 len )
01100 {
01101 #if !defined(WORDS_BIGENDIAN)
01102 memcpy(output, in, len);
01103
01104 #else
01105 Q_UINT32 i, j;
01106 for (i = 0, j = 0; j < len; i++, j += 4)
01107 {
01108 output[j] = static_cast<Q_UINT8>((in[i] & 0xff));
01109 output[j+1] = static_cast<Q_UINT8>(((in[i] >> 8) & 0xff));
01110 output[j+2] = static_cast<Q_UINT8>(((in[i] >> 16) & 0xff));
01111 output[j+3] = static_cast<Q_UINT8>(((in[i] >> 24) & 0xff));
01112 }
01113 #endif
01114 }
01115
01116
01117
01118 void KMD5::decode (Q_UINT32 *output, const unsigned char* in, Q_UINT32 len)
01119 {
01120 #if !defined(WORDS_BIGENDIAN)
01121 memcpy(output, in, len);
01122
01123 #else
01124 Q_UINT32 i, j;
01125 for (i = 0, j = 0; j < len; i++, j += 4)
01126 output[i] = static_cast<Q_UINT32>(in[j]) |
01127 (static_cast<Q_UINT32>(in[j+1]) << 8) |
01128 (static_cast<Q_UINT32>(in[j+2]) << 16) |
01129 (static_cast<Q_UINT32>(in[j+3]) << 24);
01130 #endif
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 KMD4::KMD4()
01142 {
01143 init();
01144 }
01145
01146 KMD4::KMD4(const char *in, int len)
01147 {
01148 init();
01149 update(in, len);
01150 }
01151
01152 KMD4::KMD4(const QByteArray& in)
01153 {
01154 init();
01155 update( in );
01156 }
01157
01158 KMD4::KMD4(const QCString& in)
01159 {
01160 init();
01161 update( in );
01162 }
01163
01164 void KMD4::update(const QByteArray& in)
01165 {
01166 update(in.data(), int(in.size()));
01167 }
01168
01169 void KMD4::update(const QCString& in)
01170 {
01171 update(in.data(), int(in.length()));
01172 }
01173
01174
01175
01176
01177
01178 void KMD4::update(const unsigned char *in, int len)
01179 {
01180 if (len < 0)
01181 len = qstrlen(reinterpret_cast<const char*>(in));
01182
01183 if (!len)
01184 return;
01185
01186 if (m_finalized) {
01187 kdWarning() << "KMD4::update called after state was finalized!" << endl;
01188 return;
01189 }
01190
01191 Q_UINT32 t;
01192
01193
01194
01195 t = m_count[0];
01196 if ((m_count[0] = t + ((Q_UINT32) len << 3)) < t)
01197 m_count[1]++;
01198 m_count[1] += len >> 29;
01199
01200 t = (t >> 3) & 0x3f;
01201
01202
01203
01204 if (t)
01205 {
01206 Q_UINT8 *p = &m_buffer[ t ];
01207
01208 t = 64 - t;
01209 if ((Q_UINT32)len < t)
01210 {
01211 memcpy (p, in, len);
01212 return;
01213 }
01214 memcpy (p, in, t);
01215 byteReverse (m_buffer, 16);
01216 transform (m_state, (Q_UINT32*) m_buffer);
01217 in += t;
01218 len -= t;
01219 }
01220
01221
01222 while (len >= 64)
01223 {
01224 memcpy (m_buffer, in, 64);
01225 byteReverse (m_buffer, 16);
01226 transform (m_state, (Q_UINT32 *) m_buffer);
01227 in += 64;
01228 len -= 64;
01229 }
01230
01231
01232
01233 memcpy (m_buffer, in, len);
01234 }
01235
01236 bool KMD4::update(QIODevice& file)
01237 {
01238 char buffer[1024];
01239 int len;
01240
01241 while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
01242 update(buffer, len);
01243
01244 return file.atEnd();
01245 }
01246
01247
01248
01249
01250
01251 void KMD4::finalize()
01252 {
01253 unsigned int count;
01254 unsigned char *p;
01255
01256
01257 count = (m_count[0] >> 3) & 0x3F;
01258
01259
01260
01261 p = m_buffer + count;
01262 *p++ = 0x80;
01263
01264
01265 count = 64 - 1 - count;
01266
01267
01268 if (count < 8)
01269 {
01270
01271 memset (p, 0, count);
01272 byteReverse (m_buffer, 16);
01273 transform (m_state, (Q_UINT32*) m_buffer);
01274
01275
01276 memset (m_buffer, 0, 56);
01277 }
01278 else
01279 {
01280
01281 memset (p, 0, count - 8);
01282 }
01283 byteReverse (m_buffer, 14);
01284
01285
01286 ((Q_UINT32 *) m_buffer)[14] = m_count[0];
01287 ((Q_UINT32 *) m_buffer)[15] = m_count[1];
01288
01289 transform (m_state, (Q_UINT32 *) m_buffer);
01290 byteReverse ((unsigned char *) m_state, 4);
01291
01292 memcpy (m_digest, m_state, 16);
01293 memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
01294
01295 m_finalized = true;
01296 }
01297
01298 bool KMD4::verify( const KMD4::Digest& digest)
01299 {
01300 finalize();
01301 return (0 == memcmp(rawDigest(), digest, sizeof(KMD4::Digest)));
01302 }
01303
01304 bool KMD4::verify( const QCString& hexdigest)
01305 {
01306 finalize();
01307 return (0 == strcmp(hexDigest().data(), hexdigest));
01308 }
01309
01310 const KMD4::Digest& KMD4::rawDigest()
01311 {
01312 finalize();
01313 return m_digest;
01314 }
01315
01316 void KMD4::rawDigest( KMD4::Digest& bin )
01317 {
01318 finalize();
01319 memcpy( bin, m_digest, 16 );
01320 }
01321
01322 QCString KMD4::hexDigest()
01323 {
01324 QCString s(33);
01325
01326 finalize();
01327 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
01328 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
01329 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
01330 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
01331
01332 return s;
01333 }
01334
01335 void KMD4::hexDigest(QCString& s)
01336 {
01337 finalize();
01338 s.resize(33);
01339 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
01340 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
01341 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
01342 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
01343 }
01344
01345 QCString KMD4::base64Digest()
01346 {
01347 QByteArray ba(16);
01348
01349 finalize();
01350 memcpy(ba.data(), m_digest, 16);
01351 return KCodecs::base64Encode(ba);
01352 }
01353
01354
01355 void KMD4::init()
01356 {
01357 d = 0;
01358 reset();
01359 }
01360
01361
01362
01363
01364
01365 void KMD4::reset()
01366 {
01367 m_finalized = false;
01368
01369 m_state[0] = 0x67452301;
01370 m_state[1] = 0xefcdab89;
01371 m_state[2] = 0x98badcfe;
01372 m_state[3] = 0x10325476;
01373
01374 m_count[0] = 0;
01375 m_count[1] = 0;
01376
01377 memset ( m_buffer, 0, sizeof(*m_buffer));
01378 memset ( m_digest, 0, sizeof(*m_digest));
01379 }
01380
01381
01382
01383 inline Q_UINT32 KMD4::rotate_left (Q_UINT32 x, Q_UINT32 n)
01384 {
01385 return (x << n) | (x >> (32-n)) ;
01386 }
01387
01388 inline Q_UINT32 KMD4::F (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01389 {
01390 return (x & y) | (~x & z);
01391 }
01392
01393 inline Q_UINT32 KMD4::G (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01394 {
01395 return ((x) & (y)) | ((x) & (z)) | ((y) & (z));
01396 }
01397
01398 inline Q_UINT32 KMD4::H (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
01399 {
01400 return x ^ y ^ z;
01401 }
01402
01403 inline void KMD4::FF ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01404 Q_UINT32 x, Q_UINT32 s )
01405 {
01406 a += F(b, c, d) + x;
01407 a = rotate_left (a, s);
01408 }
01409
01410 inline void KMD4::GG ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01411 Q_UINT32 x, Q_UINT32 s)
01412 {
01413 a += G(b, c, d) + x + (Q_UINT32)0x5a827999;
01414 a = rotate_left (a, s);
01415 }
01416
01417 inline void KMD4::HH ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
01418 Q_UINT32 x, Q_UINT32 s )
01419 {
01420 a += H(b, c, d) + x + (Q_UINT32)0x6ed9eba1;
01421 a = rotate_left (a, s);
01422 }
01423
01424 void KMD4::byteReverse( unsigned char *buf, Q_UINT32 len )
01425 {
01426 Q_UINT32 *b = (Q_UINT32*) buf;
01427 while ( len > 0 ) {
01428 *b = KFromToLittleEndian( *b );
01429 len--;
01430 b++;
01431 }
01432 }
01433
01434
01435
01436
01437 void KMD4::transform( Q_UINT32 buf[4], Q_UINT32 const in[16] )
01438 {
01439 Q_UINT32 a, b, c, d;
01440
01441 a = buf[0];
01442 b = buf[1];
01443 c = buf[2];
01444 d = buf[3];
01445
01446 FF (a, b, c, d, in[0], 3);
01447 FF (d, a, b, c, in[1], 7);
01448 FF (c, d, a, b, in[2], 11);
01449 FF (b, c, d, a, in[3], 19);
01450 FF (a, b, c, d, in[4], 3);
01451 FF (d, a, b, c, in[5], 7);
01452 FF (c, d, a, b, in[6], 11);
01453 FF (b, c, d, a, in[7], 19);
01454 FF (a, b, c, d, in[8], 3);
01455 FF (d, a, b, c, in[9], 7);
01456 FF (c, d, a, b, in[10], 11);
01457 FF (b, c, d, a, in[11], 19);
01458 FF (a, b, c, d, in[12], 3);
01459 FF (d, a, b, c, in[13], 7);
01460 FF (c, d, a, b, in[14], 11);
01461 FF (b, c, d, a, in[15], 19);
01462
01463 GG (a, b, c, d, in[0], 3);
01464 GG (d, a, b, c, in[4], 5);
01465 GG (c, d, a, b, in[8], 9);
01466 GG (b, c, d, a, in[12], 13);
01467 GG (a, b, c, d, in[1], 3);
01468 GG (d, a, b, c, in[5], 5);
01469 GG (c, d, a, b, in[9], 9);
01470 GG (b, c, d, a, in[13], 13);
01471 GG (a, b, c, d, in[2], 3);
01472 GG (d, a, b, c, in[6], 5);
01473 GG (c, d, a, b, in[10], 9);
01474 GG (b, c, d, a, in[14], 13);
01475 GG (a, b, c, d, in[3], 3);
01476 GG (d, a, b, c, in[7], 5);
01477 GG (c, d, a, b, in[11], 9);
01478 GG (b, c, d, a, in[15], 13);
01479
01480 HH (a, b, c, d, in[0], 3);
01481 HH (d, a, b, c, in[8], 9);
01482 HH (c, d, a, b, in[4], 11);
01483 HH (b, c, d, a, in[12], 15);
01484 HH (a, b, c, d, in[2], 3);
01485 HH (d, a, b, c, in[10], 9);
01486 HH (c, d, a, b, in[6], 11);
01487 HH (b, c, d, a, in[14], 15);
01488 HH (a, b, c, d, in[1], 3);
01489 HH (d, a, b, c, in[9], 9);
01490 HH (c, d, a, b, in[5], 11);
01491 HH (b, c, d, a, in[13], 15);
01492 HH (a, b, c, d, in[3], 3);
01493 HH (d, a, b, c, in[11], 9);
01494 HH (c, d, a, b, in[7], 11);
01495 HH (b, c, d, a, in[15], 15);
01496
01497
01498 buf[0] += a;
01499 buf[1] += b;
01500 buf[2] += c;
01501 buf[3] += d;
01502 }