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
}