• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdecore
 

kdecore

kmdcodec.cpp
00001 /*
00002    Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
00003    Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU Lesser General Public License (LGPL)
00007    version 2 as published by the Free Software Foundation.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012    GNU General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public
00015    License along with this program; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017 
00018    RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992.
00019    RSA Data Security, Inc. Created 1991. All rights reserved.
00020 
00021    The KMD5 class is based on a C++ implementation of
00022    "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by
00023    Mordechai T. Abzug,  Copyright (c) 1995.  This implementation
00024    passes the test-suite as defined in RFC 1321.
00025 
00026    The encoding and decoding utilities in KCodecs with the exception of
00027    quoted-printable are based on the java implementation in HTTPClient
00028    package by Ronald Tschal�r Copyright (C) 1996-1999.
00029 
00030    The quoted-printable codec as described in RFC 2045, section 6.7. is by
00031    Rik Hemsley (C) 2001.
00032 
00033    KMD4 class based on the LGPL code of Copyright (C) 2001 Nikos Mavroyanopoulos
00034    The algorithm is due to Ron Rivest.  This code is based on code
00035    written by Colin Plumb in 1993.
00036 */
00037 
00038 #include <config.h>
00039 
00040 #include <ctype.h>
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <stdlib.h>
00044 
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 /******************************** KCodecs ********************************/
00139 // strchr(3) for broken systems.
00140 static int rikFindChar(const char * _s, const char c)
00141 {
00142   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 TQCString KCodecs::quotedPrintableEncode(const TQByteArray& in, bool useCRLF)
00156 {
00157   TQByteArray out;
00158   quotedPrintableEncode (in, out, useCRLF);
00159   return TQCString (out.data(), out.size()+1);
00160 }
00161 
00162 TQCString KCodecs::quotedPrintableEncode(const TQCString& str, bool useCRLF)
00163 {
00164   if (str.isEmpty())
00165     return "";
00166 
00167   TQByteArray in (str.length());
00168   memcpy (in.data(), str.data(), str.length());
00169   return quotedPrintableEncode(in, useCRLF);
00170 }
00171 
00172 void KCodecs::quotedPrintableEncode(const TQByteArray& in, TQByteArray& 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   // Reasonable guess for output size when we're encoding
00188   // mostly-ASCII data. It doesn't really matter, because
00189   // the underlying allocation routines are quite efficient,
00190   // but it's nice to have 0 allocations in many cases.
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     // check if we have to enlarge the output buffer, use
00202     // a safety margin of 16 byte
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     // Plain ASCII chars just go straight out.
00210 
00211     if ((c >= 33) && (c <= 126) && ('=' != c))
00212     {
00213       *cursor++ = c;
00214       ++lineLength;
00215     }
00216 
00217     // Spaces need some thought. We have to encode them at eol (or eof).
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     // If we find a line break, just let it through.
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     // Anything else is converted to =XX.
00258 
00259     else
00260     {
00261       *cursor++ = '=';
00262       *cursor++ = hexChars[c / 16];
00263       *cursor++ = hexChars[c % 16];
00264 
00265       lineLength += 3;
00266     }
00267 
00268     // If we're approaching the maximum line length, do a soft line break.
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 TQCString KCodecs::quotedPrintableDecode(const TQByteArray & in)
00289 {
00290   TQByteArray out;
00291   quotedPrintableDecode (in, out);
00292   return TQCString (out.data(), out.size()+1);
00293 }
00294 
00295 TQCString KCodecs::quotedPrintableDecode(const TQCString & str)
00296 {
00297   if (str.isEmpty())
00298     return "";
00299 
00300   TQByteArray in (str.length());
00301   memcpy (in.data(), str.data(), str.length());
00302   return quotedPrintableDecode (in);
00303 }
00304 
00305 void KCodecs::quotedPrintableDecode(const TQByteArray& in, TQByteArray& out)
00306 {
00307   // clear out the output buffer
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 = toupper(in[i + 1]);
00329         char c2 = toupper(in[i + 2]);
00330 
00331         if (('\n' == c1) || ('\r' == c1 && '\n' == c2))
00332         {
00333           // Soft line break. No output.
00334           if ('\r' == c1)
00335             i += 2;        // CRLF line breaks
00336           else
00337             i += 1;
00338         }
00339         else
00340         {
00341           // =XX encoded byte.
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 TQCString KCodecs::base64Encode( const TQCString& str, bool insertLFs )
00364 {
00365     if ( str.isEmpty() )
00366         return "";
00367 
00368     TQByteArray in (str.length());
00369     memcpy( in.data(), str.data(), str.length() );
00370     return base64Encode( in, insertLFs );
00371 }
00372 
00373 TQCString KCodecs::base64Encode( const TQByteArray& in, bool insertLFs )
00374 {
00375     TQByteArray out;
00376     base64Encode( in, out, insertLFs );
00377     return TQCString( out.data(), out.size()+1 );
00378 }
00379 
00380 void KCodecs::base64Encode( const TQByteArray& in, TQByteArray& out,
00381                             bool insertLFs )
00382 {
00383     // clear out the output buffer
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     // Deal with the 76 characters or less per
00396     // line limit specified in RFC 2045 on a
00397     // pre request basis.
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     // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
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     // Add padding
00445     while (didx < out.size())
00446     {
00447         out[didx] = '=';
00448         didx++;
00449     }
00450 }
00451 
00452 TQCString KCodecs::base64Decode( const TQCString& str )
00453 {
00454     if ( str.isEmpty() )
00455         return "";
00456 
00457     TQByteArray in( str.length() );
00458     memcpy( in.data(), str.data(), str.length() );
00459     return base64Decode( in );
00460 }
00461 
00462 TQCString KCodecs::base64Decode( const TQByteArray& in )
00463 {
00464     TQByteArray out;
00465     base64Decode( in, out );
00466     return TQCString( out.data(), out.size()+1 );
00467 }
00468 
00469 void KCodecs::base64Decode( const TQByteArray& in, TQByteArray& 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     // Deal with possible *nix "BEGIN" marker!!
00480     while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
00481             data[count] == '\t' || data[count] == ' ') )
00482         count++;
00483 
00484     if ( count == len )
00485         return;
00486 
00487     if ( strncasecmp(data+count, "begin", 5) == 0 )
00488     {
00489         count += 5;
00490         while ( count < len && data[count] != '\n' && data[count] != '\r' )
00491             count++;
00492 
00493         while ( count < len && (data[count] == '\n' || data[count] == '\r') )
00494             count ++;
00495 
00496         data += count;
00497         tail = (len -= count);
00498     }
00499 
00500     // Find the tail end of the actual encoded data even if
00501     // there is/are trailing CR and/or LF.
00502     while ( tail > 0
00503             && ( data[tail-1] == '=' || data[tail-1] == '\n' || data[tail-1] == '\r' ) )
00504         if ( data[--tail] != '=' ) len = tail;
00505 
00506     unsigned int outIdx = 0;
00507     out.resize( (count=len) );
00508     for (unsigned int idx = 0; idx < count; idx++)
00509     {
00510         // Adhere to RFC 2045 and ignore characters
00511         // that are not part of the encoding table.
00512         unsigned char ch = data[idx];
00513         if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||
00514             (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
00515         {
00516             out[outIdx++] = Base64DecMap[ch];
00517         }
00518         else
00519         {
00520             len--;
00521             tail--;
00522         }
00523     }
00524 
00525     // kdDebug() << "Tail size = " << tail << ", Length size = " << len << endl;
00526 
00527     // 4-byte to 3-byte conversion
00528     len = (tail>(len/4)) ? tail-(len/4) : 0;
00529     unsigned int sidx = 0, didx = 0;
00530     if ( len > 1 )
00531     {
00532       while (didx < len-2)
00533       {
00534           out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
00535           out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
00536           out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077));
00537           sidx += 4;
00538           didx += 3;
00539       }
00540     }
00541 
00542     if (didx < len)
00543         out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
00544 
00545     if (++didx < len )
00546         out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
00547 
00548     // Resize the output buffer
00549     if ( len == 0 || len < out.size() )
00550       out.resize(len);
00551 }
00552 
00553 TQCString KCodecs::uuencode( const TQCString& str )
00554 {
00555     if ( str.isEmpty() )
00556         return "";
00557 
00558     TQByteArray in;
00559     in.resize( str.length() );
00560     memcpy( in.data(), str.data(), str.length() );
00561     return uuencode( in );
00562 }
00563 
00564 TQCString KCodecs::uuencode( const TQByteArray& in )
00565 {
00566     TQByteArray out;
00567     uuencode( in, out );
00568     return TQCString( out.data(), out.size()+1 );
00569 }
00570 
00571 void KCodecs::uuencode( const TQByteArray& in, TQByteArray& out )
00572 {
00573     out.resize( 0 );
00574     if( in.isEmpty() )
00575         return;
00576 
00577     unsigned int sidx = 0;
00578     unsigned int didx = 0;
00579     unsigned int line_len = 45;
00580 
00581     const char nl[] = "\n";
00582     const char* data = in.data();
00583     const unsigned int nl_len = strlen(nl);
00584     const unsigned int len = in.size();
00585 
00586     out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );
00587     // split into lines, adding line-length and line terminator
00588     while (sidx+line_len < len)
00589     {
00590         // line length
00591         out[didx++] = UUEncMap[line_len];
00592 
00593         // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
00594         for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)
00595         {
00596             out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00597             out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00598                                    (data[sidx] << 4) & 077];
00599             out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
00600                                 (data[sidx+1] << 2) & 077];
00601             out[didx++] = UUEncMap[data[sidx+2] & 077];
00602         }
00603 
00604         // line terminator
00605         //for (unsigned int idx=0; idx < nl_len; idx++)
00606         //out[didx++] = nl[idx];
00607         memcpy(out.data()+didx, nl, nl_len);
00608         didx += nl_len;
00609     }
00610 
00611     // line length
00612     out[didx++] = UUEncMap[len-sidx];
00613     // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
00614     while (sidx+2 < len)
00615     {
00616         out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00617         out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00618                                (data[sidx] << 4) & 077];
00619         out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
00620                                (data[sidx+1] << 2) & 077];
00621         out[didx++] = UUEncMap[data[sidx+2] & 077];
00622         sidx += 3;
00623     }
00624 
00625     if (sidx < len-1)
00626     {
00627         out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00628         out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
00629                                (data[sidx] << 4) & 077];
00630         out[didx++] = UUEncMap[(data[sidx+1] << 2) & 077];
00631         out[didx++] = UUEncMap[0];
00632     }
00633     else if (sidx < len)
00634     {
00635         out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
00636         out[didx++] = UUEncMap[(data[sidx] << 4) & 077];
00637         out[didx++] = UUEncMap[0];
00638         out[didx++] = UUEncMap[0];
00639     }
00640 
00641     // line terminator
00642     memcpy(out.data()+didx, nl, nl_len);
00643     didx += nl_len;
00644 
00645     // sanity check
00646     if ( didx != out.size() )
00647         out.resize( 0 );
00648 }
00649 
00650 TQCString KCodecs::uudecode( const TQCString& str )
00651 {
00652     if ( str.isEmpty() )
00653         return "";
00654 
00655     TQByteArray in;
00656     in.resize( str.length() );
00657     memcpy( in.data(), str.data(), str.length() );
00658     return uudecode( in );
00659 }
00660 
00661 TQCString KCodecs::uudecode( const TQByteArray& in )
00662 {
00663     TQByteArray out;
00664     uudecode( in, out );
00665     return TQCString( out.data(), out.size()+1 );
00666 }
00667 
00668 void KCodecs::uudecode( const TQByteArray& in, TQByteArray& out )
00669 {
00670     out.resize( 0 );
00671     if( in.isEmpty() )
00672         return;
00673 
00674     unsigned int sidx = 0;
00675     unsigned int didx = 0;
00676     unsigned int len = in.size();
00677     unsigned int line_len, end;
00678     const char* data = in.data();
00679 
00680     // Deal with *nix "BEGIN"/"END" separators!!
00681     unsigned int count = 0;
00682     while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
00683             data[count] == '\t' || data[count] == ' ') )
00684         count ++;
00685 
00686     bool hasLF = false;
00687     if ( strncasecmp( data+count, "begin", 5) == 0 )
00688     {
00689         count += 5;
00690         while ( count < len && data[count] != '\n' && data[count] != '\r' )
00691             count ++;
00692 
00693         while ( count < len && (data[count] == '\n' || data[count] == '\r') )
00694             count ++;
00695 
00696         data += count;
00697         len -= count;
00698         hasLF = true;
00699     }
00700 
00701     out.resize( len/4*3 );
00702     while ( sidx < len )
00703     {
00704         // get line length (in number of encoded octets)
00705         line_len = UUDecMap[ (unsigned char) data[sidx++]];
00706         // ascii printable to 0-63 and 4-byte to 3-byte conversion
00707         end = didx+line_len;
00708         char A, B, C, D;
00709         if (end > 2) {
00710           while (didx < end-2)
00711           {
00712              A = UUDecMap[(unsigned char) data[sidx]];
00713              B = UUDecMap[(unsigned char) data[sidx+1]];
00714              C = UUDecMap[(unsigned char) data[sidx+2]];
00715              D = UUDecMap[(unsigned char) data[sidx+3]];
00716              out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
00717              out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
00718              out[didx++] = ( ((C << 6) & 255) | (D & 077) );
00719              sidx += 4;
00720           }
00721         }
00722 
00723         if (didx < end)
00724         {
00725             A = UUDecMap[(unsigned char) data[sidx]];
00726             B = UUDecMap[(unsigned char) data[sidx+1]];
00727             out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
00728         }
00729 
00730         if (didx < end)
00731         {
00732             B = UUDecMap[(unsigned char) data[sidx+1]];
00733             C = UUDecMap[(unsigned char) data[sidx+2]];
00734             out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
00735         }
00736 
00737         // skip padding
00738         while (sidx < len  && data[sidx] != '\n' && data[sidx] != '\r')
00739             sidx++;
00740 
00741         // skip end of line
00742         while (sidx < len  && (data[sidx] == '\n' || data[sidx] == '\r'))
00743             sidx++;
00744 
00745         // skip the "END" separator when present.
00746         if ( hasLF && strncasecmp( data+sidx, "end", 3) == 0 )
00747             break;
00748     }
00749 
00750     if ( didx < out.size()  )
00751         out.resize( didx );
00752 }
00753 
00754 /******************************** KMD5 ********************************/
00755 KMD5::KMD5()
00756 {
00757     init();
00758 }
00759 
00760 KMD5::KMD5(const char *in, int len)
00761 {
00762     init();
00763     update(in, len);
00764 }
00765 
00766 KMD5::KMD5(const TQByteArray& in)
00767 {
00768     init();
00769     update( in );
00770 }
00771 
00772 KMD5::KMD5(const TQCString& in)
00773 {
00774     init();
00775     update( in );
00776 }
00777 
00778 void KMD5::update(const TQByteArray& in)
00779 {
00780     update(in.data(), int(in.size()));
00781 }
00782 
00783 void KMD5::update(const TQCString& in)
00784 {
00785     update(in.data(), int(in.length()));
00786 }
00787 
00788 void KMD5::update(const unsigned char* in, int len)
00789 {
00790     if (len < 0)
00791         len = tqstrlen(reinterpret_cast<const char*>(in));
00792 
00793     if (!len)
00794         return;
00795 
00796     if (m_finalized) {
00797         kdWarning() << "KMD5::update called after state was finalized!" << endl;
00798         return;
00799     }
00800 
00801     TQ_UINT32 in_index;
00802     TQ_UINT32 buffer_index;
00803     TQ_UINT32 buffer_space;
00804     TQ_UINT32 in_length = static_cast<TQ_UINT32>( len );
00805 
00806     buffer_index = static_cast<TQ_UINT32>((m_count[0] >> 3) & 0x3F);
00807 
00808     if (  (m_count[0] += (in_length << 3))<(in_length << 3) )
00809         m_count[1]++;
00810 
00811     m_count[1] += (in_length >> 29);
00812     buffer_space = 64 - buffer_index;
00813 
00814     if (in_length >= buffer_space)
00815     {
00816         memcpy (m_buffer + buffer_index, in, buffer_space);
00817         transform (m_buffer);
00818 
00819         for (in_index = buffer_space; in_index + 63 < in_length;
00820              in_index += 64)
00821             transform (reinterpret_cast<const unsigned char*>(in+in_index));
00822 
00823         buffer_index = 0;
00824     }
00825     else
00826         in_index=0;
00827 
00828     memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);
00829 }
00830 
00831 bool KMD5::update(TQIODevice& file)
00832 {
00833     char buffer[1024];
00834     int len;
00835 
00836     while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
00837         update(buffer, len);
00838 
00839     return file.atEnd();
00840 }
00841 
00842 void KMD5::finalize ()
00843 {
00844     if (m_finalized) return;
00845 
00846     TQ_UINT8 bits[8];
00847     TQ_UINT32 index, padLen;
00848     static const unsigned char PADDING[64]=
00849     {
00850         0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00851         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00852         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00853         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00854     };
00855 
00856     encode (bits, m_count, 8);
00857     //memcpy( bits, m_count, 8 );
00858 
00859     // Pad out to 56 mod 64.
00860     index = static_cast<TQ_UINT32>((m_count[0] >> 3) & 0x3f);
00861     padLen = (index < 56) ? (56 - index) : (120 - index);
00862     update (reinterpret_cast<const char*>(PADDING), padLen);
00863 
00864     // Append length (before padding)
00865     update (reinterpret_cast<const char*>(bits), 8);
00866 
00867     // Store state in digest
00868     encode (m_digest, m_state, 16);
00869     //memcpy( m_digest, m_state, 16 );
00870 
00871     // Fill sensitive information with zero's
00872     memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
00873 
00874     m_finalized = true;
00875 }
00876 
00877 
00878 bool KMD5::verify( const KMD5::Digest& digest)
00879 {
00880     finalize();
00881     return (0 == memcmp(rawDigest(), digest, sizeof(KMD5::Digest)));
00882 }
00883 
00884 bool KMD5::verify( const TQCString& hexdigest)
00885 {
00886     finalize();
00887     return (0 == strcmp(hexDigest().data(), hexdigest));
00888 }
00889 
00890 const KMD5::Digest& KMD5::rawDigest()
00891 {
00892     finalize();
00893     return m_digest;
00894 }
00895 
00896 void KMD5::rawDigest( KMD5::Digest& bin )
00897 {
00898     finalize();
00899     memcpy( bin, m_digest, 16 );
00900 }
00901 
00902 
00903 TQCString KMD5::hexDigest()
00904 {
00905     TQCString s(33);
00906 
00907     finalize();
00908     sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
00909             m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
00910             m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
00911             m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
00912 
00913     return s;
00914 }
00915 
00916 void KMD5::hexDigest(TQCString& s)
00917 {
00918     finalize();
00919     s.resize(33);
00920     sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
00921             m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
00922             m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
00923             m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
00924 }
00925 
00926 TQCString KMD5::base64Digest()
00927 {
00928     TQByteArray ba(16);
00929 
00930     finalize();
00931     memcpy(ba.data(), m_digest, 16);
00932     return KCodecs::base64Encode(ba);
00933 }
00934 
00935 
00936 void KMD5::init()
00937 {
00938     d = 0;
00939     reset();
00940 }
00941 
00942 void KMD5::reset()
00943 {
00944     m_finalized = false;
00945 
00946     m_count[0] = 0;
00947     m_count[1] = 0;
00948 
00949     m_state[0] = 0x67452301;
00950     m_state[1] = 0xefcdab89;
00951     m_state[2] = 0x98badcfe;
00952     m_state[3] = 0x10325476;
00953 
00954     memset ( m_buffer, 0, sizeof(*m_buffer));
00955     memset ( m_digest, 0, sizeof(*m_digest));
00956 }
00957 
00958 void KMD5::transform( const unsigned char block[64] )
00959 {
00960 
00961     TQ_UINT32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];
00962 
00963     decode (x, block, 64);
00964     //memcpy( x, block, 64 );
00965 
00966     Q_ASSERT(!m_finalized);  // not just a user error, since the method is private
00967 
00968     /* Round 1 */
00969     FF (a, b, c, d, x[ 0], KMD5_S11, 0xd76aa478); /* 1 */
00970     FF (d, a, b, c, x[ 1], KMD5_S12, 0xe8c7b756); /* 2 */
00971     FF (c, d, a, b, x[ 2], KMD5_S13, 0x242070db); /* 3 */
00972     FF (b, c, d, a, x[ 3], KMD5_S14, 0xc1bdceee); /* 4 */
00973     FF (a, b, c, d, x[ 4], KMD5_S11, 0xf57c0faf); /* 5 */
00974     FF (d, a, b, c, x[ 5], KMD5_S12, 0x4787c62a); /* 6 */
00975     FF (c, d, a, b, x[ 6], KMD5_S13, 0xa8304613); /* 7 */
00976     FF (b, c, d, a, x[ 7], KMD5_S14, 0xfd469501); /* 8 */
00977     FF (a, b, c, d, x[ 8], KMD5_S11, 0x698098d8); /* 9 */
00978     FF (d, a, b, c, x[ 9], KMD5_S12, 0x8b44f7af); /* 10 */
00979     FF (c, d, a, b, x[10], KMD5_S13, 0xffff5bb1); /* 11 */
00980     FF (b, c, d, a, x[11], KMD5_S14, 0x895cd7be); /* 12 */
00981     FF (a, b, c, d, x[12], KMD5_S11, 0x6b901122); /* 13 */
00982     FF (d, a, b, c, x[13], KMD5_S12, 0xfd987193); /* 14 */
00983     FF (c, d, a, b, x[14], KMD5_S13, 0xa679438e); /* 15 */
00984     FF (b, c, d, a, x[15], KMD5_S14, 0x49b40821); /* 16 */
00985 
00986     /* Round 2 */
00987     GG (a, b, c, d, x[ 1], KMD5_S21, 0xf61e2562); /* 17 */
00988     GG (d, a, b, c, x[ 6], KMD5_S22, 0xc040b340); /* 18 */
00989     GG (c, d, a, b, x[11], KMD5_S23, 0x265e5a51); /* 19 */
00990     GG (b, c, d, a, x[ 0], KMD5_S24, 0xe9b6c7aa); /* 20 */
00991     GG (a, b, c, d, x[ 5], KMD5_S21, 0xd62f105d); /* 21 */
00992     GG (d, a, b, c, x[10], KMD5_S22,  0x2441453); /* 22 */
00993     GG (c, d, a, b, x[15], KMD5_S23, 0xd8a1e681); /* 23 */
00994     GG (b, c, d, a, x[ 4], KMD5_S24, 0xe7d3fbc8); /* 24 */
00995     GG (a, b, c, d, x[ 9], KMD5_S21, 0x21e1cde6); /* 25 */
00996     GG (d, a, b, c, x[14], KMD5_S22, 0xc33707d6); /* 26 */
00997     GG (c, d, a, b, x[ 3], KMD5_S23, 0xf4d50d87); /* 27 */
00998     GG (b, c, d, a, x[ 8], KMD5_S24, 0x455a14ed); /* 28 */
00999     GG (a, b, c, d, x[13], KMD5_S21, 0xa9e3e905); /* 29 */
01000     GG (d, a, b, c, x[ 2], KMD5_S22, 0xfcefa3f8); /* 30 */
01001     GG (c, d, a, b, x[ 7], KMD5_S23, 0x676f02d9); /* 31 */
01002     GG (b, c, d, a, x[12], KMD5_S24, 0x8d2a4c8a); /* 32 */
01003 
01004     /* Round 3 */
01005     HH (a, b, c, d, x[ 5], KMD5_S31, 0xfffa3942); /* 33 */
01006     HH (d, a, b, c, x[ 8], KMD5_S32, 0x8771f681); /* 34 */
01007     HH (c, d, a, b, x[11], KMD5_S33, 0x6d9d6122); /* 35 */
01008     HH (b, c, d, a, x[14], KMD5_S34, 0xfde5380c); /* 36 */
01009     HH (a, b, c, d, x[ 1], KMD5_S31, 0xa4beea44); /* 37 */
01010     HH (d, a, b, c, x[ 4], KMD5_S32, 0x4bdecfa9); /* 38 */
01011     HH (c, d, a, b, x[ 7], KMD5_S33, 0xf6bb4b60); /* 39 */
01012     HH (b, c, d, a, x[10], KMD5_S34, 0xbebfbc70); /* 40 */
01013     HH (a, b, c, d, x[13], KMD5_S31, 0x289b7ec6); /* 41 */
01014     HH (d, a, b, c, x[ 0], KMD5_S32, 0xeaa127fa); /* 42 */
01015     HH (c, d, a, b, x[ 3], KMD5_S33, 0xd4ef3085); /* 43 */
01016     HH (b, c, d, a, x[ 6], KMD5_S34,  0x4881d05); /* 44 */
01017     HH (a, b, c, d, x[ 9], KMD5_S31, 0xd9d4d039); /* 45 */
01018     HH (d, a, b, c, x[12], KMD5_S32, 0xe6db99e5); /* 46 */
01019     HH (c, d, a, b, x[15], KMD5_S33, 0x1fa27cf8); /* 47 */
01020     HH (b, c, d, a, x[ 2], KMD5_S34, 0xc4ac5665); /* 48 */
01021 
01022     /* Round 4 */
01023     II (a, b, c, d, x[ 0], KMD5_S41, 0xf4292244); /* 49 */
01024     II (d, a, b, c, x[ 7], KMD5_S42, 0x432aff97); /* 50 */
01025     II (c, d, a, b, x[14], KMD5_S43, 0xab9423a7); /* 51 */
01026     II (b, c, d, a, x[ 5], KMD5_S44, 0xfc93a039); /* 52 */
01027     II (a, b, c, d, x[12], KMD5_S41, 0x655b59c3); /* 53 */
01028     II (d, a, b, c, x[ 3], KMD5_S42, 0x8f0ccc92); /* 54 */
01029     II (c, d, a, b, x[10], KMD5_S43, 0xffeff47d); /* 55 */
01030     II (b, c, d, a, x[ 1], KMD5_S44, 0x85845dd1); /* 56 */
01031     II (a, b, c, d, x[ 8], KMD5_S41, 0x6fa87e4f); /* 57 */
01032     II (d, a, b, c, x[15], KMD5_S42, 0xfe2ce6e0); /* 58 */
01033     II (c, d, a, b, x[ 6], KMD5_S43, 0xa3014314); /* 59 */
01034     II (b, c, d, a, x[13], KMD5_S44, 0x4e0811a1); /* 60 */
01035     II (a, b, c, d, x[ 4], KMD5_S41, 0xf7537e82); /* 61 */
01036     II (d, a, b, c, x[11], KMD5_S42, 0xbd3af235); /* 62 */
01037     II (c, d, a, b, x[ 2], KMD5_S43, 0x2ad7d2bb); /* 63 */
01038     II (b, c, d, a, x[ 9], KMD5_S44, 0xeb86d391); /* 64 */
01039 
01040     m_state[0] += a;
01041     m_state[1] += b;
01042     m_state[2] += c;
01043     m_state[3] += d;
01044 
01045     memset ( static_cast<void *>(x), 0, sizeof(x) );
01046 }
01047 
01048 inline TQ_UINT32 KMD5::rotate_left (TQ_UINT32 x, TQ_UINT32 n)
01049 {
01050     return (x << n) | (x >> (32-n))  ;
01051 }
01052 
01053 inline TQ_UINT32 KMD5::F (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
01054 {
01055     return (x & y) | (~x & z);
01056 }
01057 
01058 inline TQ_UINT32 KMD5::G (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
01059 {
01060     return (x & z) | (y & ~z);
01061 }
01062 
01063 inline TQ_UINT32 KMD5::H (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
01064 {
01065     return x ^ y ^ z;
01066 }
01067 
01068 inline TQ_UINT32 KMD5::I (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
01069 {
01070     return y ^ (x | ~z);
01071 }
01072 
01073 void KMD5::FF ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
01074                        TQ_UINT32 x, TQ_UINT32  s, TQ_UINT32 ac )
01075 {
01076     a += F(b, c, d) + x + ac;
01077     a = rotate_left (a, s) +b;
01078 }
01079 
01080 void KMD5::GG ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
01081                  TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac)
01082 {
01083     a += G(b, c, d) + x + ac;
01084     a = rotate_left (a, s) +b;
01085 }
01086 
01087 void KMD5::HH ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
01088                  TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac )
01089 {
01090     a += H(b, c, d) + x + ac;
01091     a = rotate_left (a, s) +b;
01092 }
01093 
01094 void KMD5::II ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
01095                  TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac )
01096 {
01097     a += I(b, c, d) + x + ac;
01098     a = rotate_left (a, s) +b;
01099 }
01100 
01101 
01102 void KMD5::encode ( unsigned char* output, TQ_UINT32 *in, TQ_UINT32 len )
01103 {
01104 #if !defined(WORDS_BIGENDIAN)
01105     memcpy(output, in, len);
01106 
01107 #else
01108     TQ_UINT32 i, j;
01109     for (i = 0, j = 0; j < len; i++, j += 4)
01110     {
01111         output[j]   = static_cast<TQ_UINT8>((in[i] & 0xff));
01112         output[j+1] = static_cast<TQ_UINT8>(((in[i] >> 8) & 0xff));
01113         output[j+2] = static_cast<TQ_UINT8>(((in[i] >> 16) & 0xff));
01114         output[j+3] = static_cast<TQ_UINT8>(((in[i] >> 24) & 0xff));
01115     }
01116 #endif
01117 }
01118 
01119 // Decodes in (TQ_UINT8) into output (TQ_UINT32). Assumes len is a
01120 // multiple of 4.
01121 void KMD5::decode (TQ_UINT32 *output, const unsigned char* in, TQ_UINT32 len)
01122 {
01123 #if !defined(WORDS_BIGENDIAN)
01124     memcpy(output, in, len);
01125 
01126 #else
01127     TQ_UINT32 i, j;
01128     for (i = 0, j = 0; j < len; i++, j += 4)
01129         output[i] = static_cast<TQ_UINT32>(in[j]) |
01130                     (static_cast<TQ_UINT32>(in[j+1]) << 8)  |
01131                     (static_cast<TQ_UINT32>(in[j+2]) << 16) |
01132                     (static_cast<TQ_UINT32>(in[j+3]) << 24);
01133 #endif
01134 }
01135 
01136 
01137 
01138 /**************************************************************/
01139 
01140 
01141 
01142 /***********************************************************/
01143 
01144 KMD4::KMD4()
01145 {
01146     init();
01147 }
01148 
01149 KMD4::KMD4(const char *in, int len)
01150 {
01151     init();
01152     update(in, len);
01153 }
01154 
01155 KMD4::KMD4(const TQByteArray& in)
01156 {
01157     init();
01158     update( in );
01159 }
01160 
01161 KMD4::KMD4(const TQCString& in)
01162 {
01163     init();
01164     update( in );
01165 }
01166 
01167 void KMD4::update(const TQByteArray& in)
01168 {
01169     update(in.data(), int(in.size()));
01170 }
01171 
01172 void KMD4::update(const TQCString& in)
01173 {
01174     update(in.data(), int(in.length()));
01175 }
01176 
01177 /*
01178  * Update context to reflect the concatenation of another buffer full
01179  * of bytes.
01180  */
01181 void KMD4::update(const unsigned char *in, int len)
01182 {
01183   if (len < 0)
01184       len = tqstrlen(reinterpret_cast<const char*>(in));
01185 
01186   if (!len)
01187       return;
01188 
01189   if (m_finalized) {
01190       kdWarning() << "KMD4::update called after state was finalized!" << endl;
01191       return;
01192   }
01193 
01194   TQ_UINT32 t;
01195 
01196   /* Update bitcount */
01197 
01198   t = m_count[0];
01199   if ((m_count[0] = t + ((TQ_UINT32) len << 3)) < t)
01200     m_count[1]++;       /* Carry from low to high */
01201   m_count[1] += len >> 29;
01202 
01203   t = (t >> 3) & 0x3f;      /* Bytes already in shsInfo->data */
01204 
01205   /* Handle any leading odd-sized chunks */
01206 
01207   if (t)
01208     {
01209       TQ_UINT8 *p = &m_buffer[ t ];
01210 
01211       t = 64 - t;
01212       if ((TQ_UINT32)len < t)
01213     {
01214       memcpy (p, in, len);
01215       return;
01216     }
01217       memcpy (p, in, t);
01218       byteReverse (m_buffer, 16);
01219       transform (m_state, (TQ_UINT32*) m_buffer);
01220       in += t;
01221       len -= t;
01222     }
01223   /* Process data in 64-byte chunks */
01224 
01225   while (len >= 64)
01226     {
01227       memcpy (m_buffer, in, 64);
01228       byteReverse (m_buffer, 16);
01229       transform (m_state, (TQ_UINT32 *) m_buffer);
01230       in += 64;
01231       len -= 64;
01232     }
01233 
01234   /* Handle any remaining bytes of data. */
01235 
01236   memcpy (m_buffer, in, len);
01237 }
01238 
01239 bool KMD4::update(TQIODevice& file)
01240 {
01241     char buffer[1024];
01242     int len;
01243 
01244     while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
01245         update(buffer, len);
01246 
01247     return file.atEnd();
01248 }
01249 
01250 /*
01251  * Final wrapup - pad to 64-byte boundary with the bit pattern 
01252  * 1 0* (64-bit count of bits processed, MSB-first)
01253  */
01254 void KMD4::finalize()
01255 {
01256   unsigned int count;
01257   unsigned char *p;
01258 
01259   /* Compute number of bytes mod 64 */
01260   count = (m_count[0] >> 3) & 0x3F;
01261 
01262   /* Set the first char of padding to 0x80.  This is safe since there is
01263      always at least one byte free */
01264   p = m_buffer + count;
01265   *p++ = 0x80;
01266 
01267   /* Bytes of padding needed to make 64 bytes */
01268   count = 64 - 1 - count;
01269 
01270   /* Pad out to 56 mod 64 */
01271   if (count < 8)
01272     {
01273       /* Two lots of padding:  Pad the first block to 64 bytes */
01274       memset (p, 0, count);
01275       byteReverse (m_buffer, 16);
01276       transform (m_state, (TQ_UINT32*) m_buffer);
01277 
01278       /* Now fill the next block with 56 bytes */
01279       memset (m_buffer, 0, 56);
01280     }
01281   else
01282     {
01283       /* Pad block to 56 bytes */
01284       memset (p, 0, count - 8);
01285     }
01286   byteReverse (m_buffer, 14);
01287 
01288   /* Append length in bits and transform */
01289   ((TQ_UINT32 *) m_buffer)[14] = m_count[0];
01290   ((TQ_UINT32 *) m_buffer)[15] = m_count[1];
01291 
01292   transform (m_state, (TQ_UINT32 *) m_buffer);
01293   byteReverse ((unsigned char *) m_state, 4);
01294 
01295   memcpy (m_digest, m_state, 16);
01296   memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
01297 
01298   m_finalized = true;
01299 }
01300 
01301 bool KMD4::verify( const KMD4::Digest& digest)
01302 {
01303     finalize();
01304     return (0 == memcmp(rawDigest(), digest, sizeof(KMD4::Digest)));
01305 }
01306 
01307 bool KMD4::verify( const TQCString& hexdigest)
01308 {
01309     finalize();
01310     return (0 == strcmp(hexDigest().data(), hexdigest));
01311 }
01312 
01313 const KMD4::Digest& KMD4::rawDigest()
01314 {
01315     finalize();
01316     return m_digest;
01317 }
01318 
01319 void KMD4::rawDigest( KMD4::Digest& bin )
01320 {
01321     finalize();
01322     memcpy( bin, m_digest, 16 );
01323 }
01324 
01325 TQCString KMD4::hexDigest()
01326 {
01327     TQCString s(33);
01328 
01329     finalize();
01330     sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
01331             m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
01332             m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
01333             m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
01334 //    kdDebug() << "KMD4::hexDigest() " << s << endl;
01335     return s;
01336 }
01337 
01338 void KMD4::hexDigest(TQCString& s)
01339 {
01340     finalize();
01341     s.resize(33);
01342     sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
01343             m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
01344             m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
01345             m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
01346 }
01347 
01348 TQCString KMD4::base64Digest()
01349 {
01350     TQByteArray ba(16);
01351 
01352     finalize();
01353     memcpy(ba.data(), m_digest, 16);
01354     return KCodecs::base64Encode(ba);
01355 }
01356 
01357 
01358 void KMD4::init()
01359 {
01360     d = 0;
01361     reset();
01362 }
01363 
01364 /*
01365  * Start MD4 accumulation.  Set bit count to 0 and buffer to mysterious
01366  * initialization constants.
01367  */
01368 void KMD4::reset()
01369 {
01370   m_finalized = false;
01371 
01372   m_state[0] = 0x67452301;
01373   m_state[1] = 0xefcdab89;
01374   m_state[2] = 0x98badcfe;
01375   m_state[3] = 0x10325476;
01376 
01377   m_count[0] = 0;
01378   m_count[1] = 0;
01379 
01380   memset ( m_buffer, 0, sizeof(*m_buffer));
01381   memset ( m_digest, 0, sizeof(*m_digest));
01382 }
01383 
01384 //#define rotl32(x,n)   (((x) << ((TQ_UINT32)(n))) | ((x) >> (32 - (TQ_UINT32)(n))))
01385 
01386 inline TQ_UINT32 KMD4::rotate_left (TQ_UINT32 x, TQ_UINT32 n)
01387 {
01388     return (x << n) | (x >> (32-n))  ;
01389 }
01390 
01391 inline TQ_UINT32 KMD4::F (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
01392 {
01393     return (x & y) | (~x & z);
01394 }
01395 
01396 inline TQ_UINT32 KMD4::G (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
01397 {
01398     return ((x) & (y)) | ((x) & (z)) | ((y) & (z));
01399 }
01400 
01401 inline TQ_UINT32 KMD4::H (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
01402 {
01403     return x ^ y ^ z;
01404 }
01405 
01406 inline void KMD4::FF ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
01407                        TQ_UINT32 x, TQ_UINT32  s )
01408 {
01409     a += F(b, c, d) + x;
01410     a = rotate_left (a, s);
01411 }
01412 
01413 inline void KMD4::GG ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
01414                  TQ_UINT32 x, TQ_UINT32 s)
01415 {
01416     a += G(b, c, d) + x + (TQ_UINT32)0x5a827999;
01417     a = rotate_left (a, s);
01418 }
01419 
01420 inline void KMD4::HH ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
01421                  TQ_UINT32 x, TQ_UINT32 s )
01422 {
01423     a += H(b, c, d) + x + (TQ_UINT32)0x6ed9eba1;
01424     a = rotate_left (a, s);
01425 }
01426 
01427 void KMD4::byteReverse( unsigned char *buf, TQ_UINT32 len )
01428 {
01429 #ifdef WORDS_BIGENDIAN
01430   TQ_UINT32 *b = (TQ_UINT32*) buf;
01431   while ( len > 0 ) {
01432     *b = ((((*b) & 0xff000000) >> 24) | (((*b) & 0x00ff0000) >>  8) |
01433          (((*b) & 0x0000ff00) <<  8) | (((*b) & 0x000000ff) << 24));
01434     len--;
01435     b++;
01436   }
01437 #else
01438   Q_UNUSED(buf)
01439   Q_UNUSED(len)
01440 #endif
01441 }
01442 
01443 /*
01444  * The core of the MD4 algorithm
01445  */
01446 void KMD4::transform( TQ_UINT32 buf[4], TQ_UINT32 const in[16] )
01447 {
01448   TQ_UINT32 a, b, c, d;
01449 
01450   a = buf[0];
01451   b = buf[1];
01452   c = buf[2];
01453   d = buf[3];
01454 
01455   FF (a, b, c, d, in[0], 3);    /* 1 */
01456   FF (d, a, b, c, in[1], 7);    /* 2 */
01457   FF (c, d, a, b, in[2], 11);   /* 3 */
01458   FF (b, c, d, a, in[3], 19);   /* 4 */
01459   FF (a, b, c, d, in[4], 3);    /* 5 */
01460   FF (d, a, b, c, in[5], 7);    /* 6 */
01461   FF (c, d, a, b, in[6], 11);   /* 7 */
01462   FF (b, c, d, a, in[7], 19);   /* 8 */
01463   FF (a, b, c, d, in[8], 3);    /* 9 */
01464   FF (d, a, b, c, in[9], 7);    /* 10 */
01465   FF (c, d, a, b, in[10], 11);  /* 11 */
01466   FF (b, c, d, a, in[11], 19);  /* 12 */
01467   FF (a, b, c, d, in[12], 3);   /* 13 */
01468   FF (d, a, b, c, in[13], 7);   /* 14 */
01469   FF (c, d, a, b, in[14], 11);  /* 15 */
01470   FF (b, c, d, a, in[15], 19);  /* 16 */
01471 
01472   GG (a, b, c, d, in[0], 3);    /* 17 */
01473   GG (d, a, b, c, in[4], 5);    /* 18 */
01474   GG (c, d, a, b, in[8], 9);    /* 19 */
01475   GG (b, c, d, a, in[12], 13);  /* 20 */
01476   GG (a, b, c, d, in[1], 3);    /* 21 */
01477   GG (d, a, b, c, in[5], 5);    /* 22 */
01478   GG (c, d, a, b, in[9], 9);    /* 23 */
01479   GG (b, c, d, a, in[13], 13);  /* 24 */
01480   GG (a, b, c, d, in[2], 3);    /* 25 */
01481   GG (d, a, b, c, in[6], 5);    /* 26 */
01482   GG (c, d, a, b, in[10], 9);   /* 27 */
01483   GG (b, c, d, a, in[14], 13);  /* 28 */
01484   GG (a, b, c, d, in[3], 3);    /* 29 */
01485   GG (d, a, b, c, in[7], 5);    /* 30 */
01486   GG (c, d, a, b, in[11], 9);   /* 31 */
01487   GG (b, c, d, a, in[15], 13);  /* 32 */
01488 
01489   HH (a, b, c, d, in[0], 3);    /* 33 */
01490   HH (d, a, b, c, in[8], 9);    /* 34 */
01491   HH (c, d, a, b, in[4], 11);   /* 35 */
01492   HH (b, c, d, a, in[12], 15);  /* 36 */
01493   HH (a, b, c, d, in[2], 3);    /* 37 */
01494   HH (d, a, b, c, in[10], 9);   /* 38 */
01495   HH (c, d, a, b, in[6], 11);   /* 39 */
01496   HH (b, c, d, a, in[14], 15);  /* 40 */
01497   HH (a, b, c, d, in[1], 3);    /* 41 */
01498   HH (d, a, b, c, in[9], 9);    /* 42 */
01499   HH (c, d, a, b, in[5], 11);   /* 43 */
01500   HH (b, c, d, a, in[13], 15);  /* 44 */
01501   HH (a, b, c, d, in[3], 3);    /* 45 */
01502   HH (d, a, b, c, in[11], 9);   /* 46 */
01503   HH (c, d, a, b, in[7], 11);   /* 47 */
01504   HH (b, c, d, a, in[15], 15);  /* 48 */
01505 
01506 
01507   buf[0] += a;
01508   buf[1] += b;
01509   buf[2] += c;
01510   buf[3] += d;
01511 }

kdecore

Skip menu "kdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdecore

Skip menu "kdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdecore by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |