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