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

tdecore

  • tdecore
kmdcodec.cpp
1 /*
2  Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
3  Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License (LGPL)
7  version 2 as published by the Free Software Foundation.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public
15  License along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 
18  RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992.
19  RSA Data Security, Inc. Created 1991. All rights reserved.
20 
21  The KMD5 class is based on a C++ implementation of
22  "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by
23  Mordechai T. Abzug, Copyright (c) 1995. This implementation
24  passes the test-suite as defined in RFC 1321.
25 
26  The encoding and decoding utilities in KCodecs with the exception of
27  quoted-printable are based on the java implementation in HTTPClient
28  package by Ronald Tschal�r Copyright (C) 1996-1999.
29 
30  The quoted-printable codec as described in RFC 2045, section 6.7. is by
31  Rik Hemsley (C) 2001.
32 
33  KMD4 class based on the LGPL code of Copyright (C) 2001 Nikos Mavroyanopoulos
34  The algorithm is due to Ron Rivest. This code is based on code
35  written by Colin Plumb in 1993.
36 */
37 
38 #include <config.h>
39 
40 #include <ctype.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <stdlib.h>
44 
45 #include <kdebug.h>
46 #include "kmdcodec.h"
47 
48 #define KMD5_S11 7
49 #define KMD5_S12 12
50 #define KMD5_S13 17
51 #define KMD5_S14 22
52 #define KMD5_S21 5
53 #define KMD5_S22 9
54 #define KMD5_S23 14
55 #define KMD5_S24 20
56 #define KMD5_S31 4
57 #define KMD5_S32 11
58 #define KMD5_S33 16
59 #define KMD5_S34 23
60 #define KMD5_S41 6
61 #define KMD5_S42 10
62 #define KMD5_S43 15
63 #define KMD5_S44 21
64 
65 const char KCodecs::Base64EncMap[64] =
66 {
67  0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
68  0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
69  0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
70  0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
71  0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
72  0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
73  0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
74  0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
75 };
76 
77 const char KCodecs::Base64DecMap[128] =
78 {
79  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84  0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
85  0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
86  0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87  0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
88  0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
89  0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
90  0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
91  0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
92  0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
93  0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
94  0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
95 };
96 
97 const char KCodecs::UUEncMap[64] =
98 {
99  0x60, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
100  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
101  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
102  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
103  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
104  0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
105  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
106  0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
107 };
108 
109 const char KCodecs::UUDecMap[128] =
110 {
111  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
116  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
117  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
118  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
119  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
120  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
121  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
122  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
123  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
127 };
128 
129 const char KCodecs::hexChars[16] =
130 {
131  '0', '1', '2', '3', '4', '5', '6', '7',
132  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
133 };
134 
135 const unsigned int KCodecs::maxQPLineLength = 70;
136 
137 
138 /******************************** KCodecs ********************************/
139 // strchr(3) for broken systems.
140 static int rikFindChar(const char * _s, const char c)
141 {
142  const char * s = _s;
143 
144  while (true)
145  {
146  if ((0 == *s) || (c == *s)) break; ++s;
147  if ((0 == *s) || (c == *s)) break; ++s;
148  if ((0 == *s) || (c == *s)) break; ++s;
149  if ((0 == *s) || (c == *s)) break; ++s;
150  }
151 
152  return s - _s;
153 }
154 
155 TQCString KCodecs::quotedPrintableEncode(const TQByteArray& in, bool useCRLF)
156 {
157  TQByteArray out;
158  quotedPrintableEncode (in, out, useCRLF);
159  return TQCString (out.data(), out.size()+1);
160 }
161 
162 TQCString KCodecs::quotedPrintableEncode(const TQCString& str, bool useCRLF)
163 {
164  if (str.isEmpty())
165  return "";
166 
167  TQByteArray in (str.length());
168  memcpy (in.data(), str.data(), str.length());
169  return quotedPrintableEncode(in, useCRLF);
170 }
171 
172 void KCodecs::quotedPrintableEncode(const TQByteArray& in, TQByteArray& out, bool useCRLF)
173 {
174  out.resize (0);
175  if (in.isEmpty())
176  return;
177 
178  char *cursor;
179  const char *data;
180  unsigned int lineLength;
181  unsigned int pos;
182 
183  const unsigned int length = in.size();
184  const unsigned int end = length - 1;
185 
186 
187  // Reasonable guess for output size when we're encoding
188  // mostly-ASCII data. It doesn't really matter, because
189  // the underlying allocation routines are quite efficient,
190  // but it's nice to have 0 allocations in many cases.
191  out.resize ((length*12)/10);
192  cursor = out.data();
193  data = in.data();
194  lineLength = 0;
195  pos = 0;
196 
197  for (unsigned int i = 0; i < length; i++)
198  {
199  unsigned char c (data[i]);
200 
201  // check if we have to enlarge the output buffer, use
202  // a safety margin of 16 byte
203  pos = cursor-out.data();
204  if (out.size()-pos < 16) {
205  out.resize(out.size()+4096);
206  cursor = out.data()+pos;
207  }
208 
209  // Plain ASCII chars just go straight out.
210 
211  if ((c >= 33) && (c <= 126) && ('=' != c))
212  {
213  *cursor++ = c;
214  ++lineLength;
215  }
216 
217  // Spaces need some thought. We have to encode them at eol (or eof).
218 
219  else if (' ' == c)
220  {
221  if
222  (
223  (i >= length)
224  ||
225  ((i < end) && ((useCRLF && ('\r' == data[i + 1]) && ('\n' == data[i + 2]))
226  ||
227  (!useCRLF && ('\n' == data[i + 1]))))
228  )
229  {
230  *cursor++ = '=';
231  *cursor++ = '2';
232  *cursor++ = '0';
233 
234  lineLength += 3;
235  }
236  else
237  {
238  *cursor++ = ' ';
239  ++lineLength;
240  }
241  }
242  // If we find a line break, just let it through.
243  else if ((useCRLF && ('\r' == c) && (i < end) && ('\n' == data[i + 1])) ||
244  (!useCRLF && ('\n' == c)))
245  {
246  lineLength = 0;
247 
248  if (useCRLF) {
249  *cursor++ = '\r';
250  *cursor++ = '\n';
251  ++i;
252  } else {
253  *cursor++ = '\n';
254  }
255  }
256 
257  // Anything else is converted to =XX.
258 
259  else
260  {
261  *cursor++ = '=';
262  *cursor++ = hexChars[c / 16];
263  *cursor++ = hexChars[c % 16];
264 
265  lineLength += 3;
266  }
267 
268  // If we're approaching the maximum line length, do a soft line break.
269 
270  if ((lineLength > maxQPLineLength) && (i < end))
271  {
272  if (useCRLF) {
273  *cursor++ = '=';
274  *cursor++ = '\r';
275  *cursor++ = '\n';
276  } else {
277  *cursor++ = '=';
278  *cursor++ = '\n';
279  }
280 
281  lineLength = 0;
282  }
283  }
284 
285  out.truncate(cursor - out.data());
286 }
287 
288 TQCString KCodecs::quotedPrintableDecode(const TQByteArray & in)
289 {
290  TQByteArray out;
291  quotedPrintableDecode (in, out);
292  return TQCString (out.data(), out.size()+1);
293 }
294 
295 TQCString KCodecs::quotedPrintableDecode(const TQCString & str)
296 {
297  if (str.isEmpty())
298  return "";
299 
300  TQByteArray in (str.length());
301  memcpy (in.data(), str.data(), str.length());
302  return quotedPrintableDecode (in);
303 }
304 
305 void KCodecs::quotedPrintableDecode(const TQByteArray& in, TQByteArray& out)
306 {
307  // clear out the output buffer
308  out.resize (0);
309  if (in.isEmpty())
310  return;
311 
312  char *cursor;
313  const char *data;
314  const unsigned int length = in.size();
315 
316  data = in.data();
317  out.resize (length);
318  cursor = out.data();
319 
320  for (unsigned int i = 0; i < length; i++)
321  {
322  char c(in[i]);
323 
324  if ('=' == c)
325  {
326  if (i < length - 2)
327  {
328  char c1 = toupper(in[i + 1]);
329  char c2 = toupper(in[i + 2]);
330 
331  if (('\n' == c1) || ('\r' == c1 && '\n' == c2))
332  {
333  // Soft line break. No output.
334  if ('\r' == c1)
335  i += 2; // CRLF line breaks
336  else
337  i += 1;
338  }
339  else
340  {
341  // =XX encoded byte.
342 
343  int hexChar0 = rikFindChar(hexChars, c1);
344  int hexChar1 = rikFindChar(hexChars, c2);
345 
346  if (hexChar0 < 16 && hexChar1 < 16)
347  {
348  *cursor++ = char((hexChar0 * 16) | hexChar1);
349  i += 2;
350  }
351  }
352  }
353  }
354  else
355  {
356  *cursor++ = c;
357  }
358  }
359 
360  out.truncate(cursor - out.data());
361 }
362 
363 TQCString KCodecs::base64Encode( const TQCString& str, bool insertLFs )
364 {
365  if ( str.isEmpty() )
366  return "";
367 
368  TQByteArray in (str.length());
369  memcpy( in.data(), str.data(), str.length() );
370  return base64Encode( in, insertLFs );
371 }
372 
373 TQCString KCodecs::base64Encode( const TQByteArray& in, bool insertLFs )
374 {
375  TQByteArray out;
376  base64Encode( in, out, insertLFs );
377  return TQCString( out.data(), out.size()+1 );
378 }
379 
380 void KCodecs::base64Encode( const TQByteArray& in, TQByteArray& out,
381  bool insertLFs )
382 {
383  // clear out the output buffer
384  out.resize (0);
385  if ( in.isEmpty() )
386  return;
387 
388  unsigned int sidx = 0;
389  unsigned int didx = 0;
390  const char* data = in.data();
391  const unsigned int len = in.size();
392 
393  unsigned int out_len = ((len+2)/3)*4;
394 
395  // Deal with the 76 characters or less per
396  // line limit specified in RFC 2045 on a
397  // pre request basis.
398  insertLFs = (insertLFs && out_len > 76);
399  if ( insertLFs )
400  out_len += ((out_len-1)/76);
401 
402  int count = 0;
403  out.resize( out_len );
404 
405  // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
406  if ( len > 1 )
407  {
408  while (sidx < len-2)
409  {
410  if ( insertLFs )
411  {
412  if ( count && (count%76) == 0 )
413  out[didx++] = '\n';
414  count += 4;
415  }
416  out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
417  out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
418  (data[sidx] << 4) & 077];
419  out[didx++] = Base64EncMap[(data[sidx+2] >> 6) & 003 |
420  (data[sidx+1] << 2) & 077];
421  out[didx++] = Base64EncMap[data[sidx+2] & 077];
422  sidx += 3;
423  }
424  }
425 
426  if (sidx < len)
427  {
428  if ( insertLFs && (count > 0) && (count%76) == 0 )
429  out[didx++] = '\n';
430 
431  out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
432  if (sidx < len-1)
433  {
434  out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
435  (data[sidx] << 4) & 077];
436  out[didx++] = Base64EncMap[(data[sidx+1] << 2) & 077];
437  }
438  else
439  {
440  out[didx++] = Base64EncMap[(data[sidx] << 4) & 077];
441  }
442  }
443 
444  // Add padding
445  while (didx < out.size())
446  {
447  out[didx] = '=';
448  didx++;
449  }
450 }
451 
452 TQCString KCodecs::base64Decode( const TQCString& str )
453 {
454  if ( str.isEmpty() )
455  return "";
456 
457  TQByteArray in( str.length() );
458  memcpy( in.data(), str.data(), str.length() );
459  return base64Decode( in );
460 }
461 
462 TQCString KCodecs::base64Decode( const TQByteArray& in )
463 {
464  TQByteArray out;
465  base64Decode( in, out );
466  return TQCString( out.data(), out.size()+1 );
467 }
468 
469 void KCodecs::base64Decode( const TQByteArray& in, TQByteArray& out )
470 {
471  out.resize(0);
472  if ( in.isEmpty() )
473  return;
474 
475  unsigned int count = 0;
476  unsigned int len = in.size(), tail = len;
477  const char* data = in.data();
478 
479  // Deal with possible *nix "BEGIN" marker!!
480  while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
481  data[count] == '\t' || data[count] == ' ') )
482  count++;
483 
484  if ( count == len )
485  return;
486 
487  if ( strncasecmp(data+count, "begin", 5) == 0 )
488  {
489  count += 5;
490  while ( count < len && data[count] != '\n' && data[count] != '\r' )
491  count++;
492 
493  while ( count < len && (data[count] == '\n' || data[count] == '\r') )
494  count ++;
495 
496  data += count;
497  tail = (len -= count);
498  }
499 
500  // Find the tail end of the actual encoded data even if
501  // there is/are trailing CR and/or LF.
502  while ( tail > 0
503  && ( data[tail-1] == '=' || data[tail-1] == '\n' || data[tail-1] == '\r' ) )
504  if ( data[--tail] != '=' ) len = tail;
505 
506  unsigned int outIdx = 0;
507  out.resize( (count=len) );
508  for (unsigned int idx = 0; idx < count; idx++)
509  {
510  // Adhere to RFC 2045 and ignore characters
511  // that are not part of the encoding table.
512  unsigned char ch = data[idx];
513  if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||
514  (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
515  {
516  out[outIdx++] = Base64DecMap[ch];
517  }
518  else
519  {
520  len--;
521  tail--;
522  }
523  }
524 
525  // kdDebug() << "Tail size = " << tail << ", Length size = " << len << endl;
526 
527  // 4-byte to 3-byte conversion
528  len = (tail>(len/4)) ? tail-(len/4) : 0;
529  unsigned int sidx = 0, didx = 0;
530  if ( len > 1 )
531  {
532  while (didx < len-2)
533  {
534  out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
535  out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
536  out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077));
537  sidx += 4;
538  didx += 3;
539  }
540  }
541 
542  if (didx < len)
543  out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
544 
545  if (++didx < len )
546  out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
547 
548  // Resize the output buffer
549  if ( len == 0 || len < out.size() )
550  out.resize(len);
551 }
552 
553 TQCString KCodecs::uuencode( const TQCString& str )
554 {
555  if ( str.isEmpty() )
556  return "";
557 
558  TQByteArray in;
559  in.resize( str.length() );
560  memcpy( in.data(), str.data(), str.length() );
561  return uuencode( in );
562 }
563 
564 TQCString KCodecs::uuencode( const TQByteArray& in )
565 {
566  TQByteArray out;
567  uuencode( in, out );
568  return TQCString( out.data(), out.size()+1 );
569 }
570 
571 void KCodecs::uuencode( const TQByteArray& in, TQByteArray& out )
572 {
573  out.resize( 0 );
574  if( in.isEmpty() )
575  return;
576 
577  unsigned int sidx = 0;
578  unsigned int didx = 0;
579  unsigned int line_len = 45;
580 
581  const char nl[] = "\n";
582  const char* data = in.data();
583  const unsigned int nl_len = strlen(nl);
584  const unsigned int len = in.size();
585 
586  out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );
587  // split into lines, adding line-length and line terminator
588  while (sidx+line_len < len)
589  {
590  // line length
591  out[didx++] = UUEncMap[line_len];
592 
593  // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
594  for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)
595  {
596  out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
597  out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
598  (data[sidx] << 4) & 077];
599  out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
600  (data[sidx+1] << 2) & 077];
601  out[didx++] = UUEncMap[data[sidx+2] & 077];
602  }
603 
604  // line terminator
605  //for (unsigned int idx=0; idx < nl_len; idx++)
606  //out[didx++] = nl[idx];
607  memcpy(out.data()+didx, nl, nl_len);
608  didx += nl_len;
609  }
610 
611  // line length
612  out[didx++] = UUEncMap[len-sidx];
613  // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
614  while (sidx+2 < len)
615  {
616  out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
617  out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
618  (data[sidx] << 4) & 077];
619  out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
620  (data[sidx+1] << 2) & 077];
621  out[didx++] = UUEncMap[data[sidx+2] & 077];
622  sidx += 3;
623  }
624 
625  if (sidx < len-1)
626  {
627  out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
628  out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
629  (data[sidx] << 4) & 077];
630  out[didx++] = UUEncMap[(data[sidx+1] << 2) & 077];
631  out[didx++] = UUEncMap[0];
632  }
633  else if (sidx < len)
634  {
635  out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
636  out[didx++] = UUEncMap[(data[sidx] << 4) & 077];
637  out[didx++] = UUEncMap[0];
638  out[didx++] = UUEncMap[0];
639  }
640 
641  // line terminator
642  memcpy(out.data()+didx, nl, nl_len);
643  didx += nl_len;
644 
645  // sanity check
646  if ( didx != out.size() )
647  out.resize( 0 );
648 }
649 
650 TQCString KCodecs::uudecode( const TQCString& str )
651 {
652  if ( str.isEmpty() )
653  return "";
654 
655  TQByteArray in;
656  in.resize( str.length() );
657  memcpy( in.data(), str.data(), str.length() );
658  return uudecode( in );
659 }
660 
661 TQCString KCodecs::uudecode( const TQByteArray& in )
662 {
663  TQByteArray out;
664  uudecode( in, out );
665  return TQCString( out.data(), out.size()+1 );
666 }
667 
668 void KCodecs::uudecode( const TQByteArray& in, TQByteArray& out )
669 {
670  out.resize( 0 );
671  if( in.isEmpty() )
672  return;
673 
674  unsigned int sidx = 0;
675  unsigned int didx = 0;
676  unsigned int len = in.size();
677  unsigned int line_len, end;
678  const char* data = in.data();
679 
680  // Deal with *nix "BEGIN"/"END" separators!!
681  unsigned int count = 0;
682  while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
683  data[count] == '\t' || data[count] == ' ') )
684  count ++;
685 
686  bool hasLF = false;
687  if ( strncasecmp( data+count, "begin", 5) == 0 )
688  {
689  count += 5;
690  while ( count < len && data[count] != '\n' && data[count] != '\r' )
691  count ++;
692 
693  while ( count < len && (data[count] == '\n' || data[count] == '\r') )
694  count ++;
695 
696  data += count;
697  len -= count;
698  hasLF = true;
699  }
700 
701  out.resize( len/4*3 );
702  while ( sidx < len )
703  {
704  // get line length (in number of encoded octets)
705  line_len = UUDecMap[ (unsigned char) data[sidx++]];
706  // ascii printable to 0-63 and 4-byte to 3-byte conversion
707  end = didx+line_len;
708  char A, B, C, D;
709  if (end > 2) {
710  while (didx < end-2)
711  {
712  A = UUDecMap[(unsigned char) data[sidx]];
713  B = UUDecMap[(unsigned char) data[sidx+1]];
714  C = UUDecMap[(unsigned char) data[sidx+2]];
715  D = UUDecMap[(unsigned char) data[sidx+3]];
716  out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
717  out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
718  out[didx++] = ( ((C << 6) & 255) | (D & 077) );
719  sidx += 4;
720  }
721  }
722 
723  if (didx < end)
724  {
725  A = UUDecMap[(unsigned char) data[sidx]];
726  B = UUDecMap[(unsigned char) data[sidx+1]];
727  out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
728  }
729 
730  if (didx < end)
731  {
732  B = UUDecMap[(unsigned char) data[sidx+1]];
733  C = UUDecMap[(unsigned char) data[sidx+2]];
734  out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
735  }
736 
737  // skip padding
738  while (sidx < len && data[sidx] != '\n' && data[sidx] != '\r')
739  sidx++;
740 
741  // skip end of line
742  while (sidx < len && (data[sidx] == '\n' || data[sidx] == '\r'))
743  sidx++;
744 
745  // skip the "END" separator when present.
746  if ( hasLF && strncasecmp( data+sidx, "end", 3) == 0 )
747  break;
748  }
749 
750  if ( didx < out.size() )
751  out.resize( didx );
752 }
753 
754 /******************************** KMD5 ********************************/
755 KMD5::KMD5()
756 {
757  init();
758 }
759 
760 KMD5::KMD5(const char *in, int len)
761 {
762  init();
763  update(in, len);
764 }
765 
766 KMD5::KMD5(const TQByteArray& in)
767 {
768  init();
769  update( in );
770 }
771 
772 KMD5::KMD5(const TQCString& in)
773 {
774  init();
775  update( in );
776 }
777 
778 void KMD5::update(const TQByteArray& in)
779 {
780  update(in.data(), int(in.size()));
781 }
782 
783 void KMD5::update(const TQCString& in)
784 {
785  update(in.data(), int(in.length()));
786 }
787 
788 void KMD5::update(const unsigned char* in, int len)
789 {
790  if (len < 0)
791  len = tqstrlen(reinterpret_cast<const char*>(in));
792 
793  if (!len)
794  return;
795 
796  if (m_finalized) {
797  kdWarning() << "KMD5::update called after state was finalized!" << endl;
798  return;
799  }
800 
801  TQ_UINT32 in_index;
802  TQ_UINT32 buffer_index;
803  TQ_UINT32 buffer_space;
804  TQ_UINT32 in_length = static_cast<TQ_UINT32>( len );
805 
806  buffer_index = static_cast<TQ_UINT32>((m_count[0] >> 3) & 0x3F);
807 
808  if ( (m_count[0] += (in_length << 3))<(in_length << 3) )
809  m_count[1]++;
810 
811  m_count[1] += (in_length >> 29);
812  buffer_space = 64 - buffer_index;
813 
814  if (in_length >= buffer_space)
815  {
816  memcpy (m_buffer + buffer_index, in, buffer_space);
817  transform (m_buffer);
818 
819  for (in_index = buffer_space; in_index + 63 < in_length;
820  in_index += 64)
821  transform (reinterpret_cast<const unsigned char*>(in+in_index));
822 
823  buffer_index = 0;
824  }
825  else
826  in_index=0;
827 
828  memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);
829 }
830 
831 bool KMD5::update(TQIODevice& file)
832 {
833  char buffer[1024];
834  int len;
835 
836  while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
837  update(buffer, len);
838 
839  return file.atEnd();
840 }
841 
842 void KMD5::finalize ()
843 {
844  if (m_finalized) return;
845 
846  TQ_UINT8 bits[8];
847  TQ_UINT32 index, padLen;
848  static const unsigned char PADDING[64]=
849  {
850  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
851  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
852  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
853  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
854  };
855 
856  encode (bits, m_count, 8);
857  //memcpy( bits, m_count, 8 );
858 
859  // Pad out to 56 mod 64.
860  index = static_cast<TQ_UINT32>((m_count[0] >> 3) & 0x3f);
861  padLen = (index < 56) ? (56 - index) : (120 - index);
862  update (reinterpret_cast<const char*>(PADDING), padLen);
863 
864  // Append length (before padding)
865  update (reinterpret_cast<const char*>(bits), 8);
866 
867  // Store state in digest
868  encode (m_digest, m_state, 16);
869  //memcpy( m_digest, m_state, 16 );
870 
871  // Fill sensitive information with zero's
872  memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
873 
874  m_finalized = true;
875 }
876 
877 
878 bool KMD5::verify( const KMD5::Digest& digest)
879 {
880  finalize();
881  return (0 == memcmp(rawDigest(), digest, sizeof(KMD5::Digest)));
882 }
883 
884 bool KMD5::verify( const TQCString& hexdigest)
885 {
886  finalize();
887  return (0 == strcmp(hexDigest().data(), hexdigest));
888 }
889 
890 const KMD5::Digest& KMD5::rawDigest()
891 {
892  finalize();
893  return m_digest;
894 }
895 
896 void KMD5::rawDigest( KMD5::Digest& bin )
897 {
898  finalize();
899  memcpy( bin, m_digest, 16 );
900 }
901 
902 
903 TQCString KMD5::hexDigest()
904 {
905  TQCString s(33);
906 
907  finalize();
908  sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
909  m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
910  m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
911  m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
912 
913  return s;
914 }
915 
916 void KMD5::hexDigest(TQCString& s)
917 {
918  finalize();
919  s.resize(33);
920  sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
921  m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
922  m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
923  m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
924 }
925 
926 TQCString KMD5::base64Digest()
927 {
928  TQByteArray ba(16);
929 
930  finalize();
931  memcpy(ba.data(), m_digest, 16);
932  return KCodecs::base64Encode(ba);
933 }
934 
935 
936 void KMD5::init()
937 {
938  d = 0;
939  reset();
940 }
941 
942 void KMD5::reset()
943 {
944  m_finalized = false;
945 
946  m_count[0] = 0;
947  m_count[1] = 0;
948 
949  m_state[0] = 0x67452301;
950  m_state[1] = 0xefcdab89;
951  m_state[2] = 0x98badcfe;
952  m_state[3] = 0x10325476;
953 
954  memset ( m_buffer, 0, sizeof(*m_buffer));
955  memset ( m_digest, 0, sizeof(*m_digest));
956 }
957 
958 void KMD5::transform( const unsigned char block[64] )
959 {
960 
961  TQ_UINT32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];
962 
963  decode (x, block, 64);
964  //memcpy( x, block, 64 );
965 
966  Q_ASSERT(!m_finalized); // not just a user error, since the method is private
967 
968  /* Round 1 */
969  FF (a, b, c, d, x[ 0], KMD5_S11, 0xd76aa478); /* 1 */
970  FF (d, a, b, c, x[ 1], KMD5_S12, 0xe8c7b756); /* 2 */
971  FF (c, d, a, b, x[ 2], KMD5_S13, 0x242070db); /* 3 */
972  FF (b, c, d, a, x[ 3], KMD5_S14, 0xc1bdceee); /* 4 */
973  FF (a, b, c, d, x[ 4], KMD5_S11, 0xf57c0faf); /* 5 */
974  FF (d, a, b, c, x[ 5], KMD5_S12, 0x4787c62a); /* 6 */
975  FF (c, d, a, b, x[ 6], KMD5_S13, 0xa8304613); /* 7 */
976  FF (b, c, d, a, x[ 7], KMD5_S14, 0xfd469501); /* 8 */
977  FF (a, b, c, d, x[ 8], KMD5_S11, 0x698098d8); /* 9 */
978  FF (d, a, b, c, x[ 9], KMD5_S12, 0x8b44f7af); /* 10 */
979  FF (c, d, a, b, x[10], KMD5_S13, 0xffff5bb1); /* 11 */
980  FF (b, c, d, a, x[11], KMD5_S14, 0x895cd7be); /* 12 */
981  FF (a, b, c, d, x[12], KMD5_S11, 0x6b901122); /* 13 */
982  FF (d, a, b, c, x[13], KMD5_S12, 0xfd987193); /* 14 */
983  FF (c, d, a, b, x[14], KMD5_S13, 0xa679438e); /* 15 */
984  FF (b, c, d, a, x[15], KMD5_S14, 0x49b40821); /* 16 */
985 
986  /* Round 2 */
987  GG (a, b, c, d, x[ 1], KMD5_S21, 0xf61e2562); /* 17 */
988  GG (d, a, b, c, x[ 6], KMD5_S22, 0xc040b340); /* 18 */
989  GG (c, d, a, b, x[11], KMD5_S23, 0x265e5a51); /* 19 */
990  GG (b, c, d, a, x[ 0], KMD5_S24, 0xe9b6c7aa); /* 20 */
991  GG (a, b, c, d, x[ 5], KMD5_S21, 0xd62f105d); /* 21 */
992  GG (d, a, b, c, x[10], KMD5_S22, 0x2441453); /* 22 */
993  GG (c, d, a, b, x[15], KMD5_S23, 0xd8a1e681); /* 23 */
994  GG (b, c, d, a, x[ 4], KMD5_S24, 0xe7d3fbc8); /* 24 */
995  GG (a, b, c, d, x[ 9], KMD5_S21, 0x21e1cde6); /* 25 */
996  GG (d, a, b, c, x[14], KMD5_S22, 0xc33707d6); /* 26 */
997  GG (c, d, a, b, x[ 3], KMD5_S23, 0xf4d50d87); /* 27 */
998  GG (b, c, d, a, x[ 8], KMD5_S24, 0x455a14ed); /* 28 */
999  GG (a, b, c, d, x[13], KMD5_S21, 0xa9e3e905); /* 29 */
1000  GG (d, a, b, c, x[ 2], KMD5_S22, 0xfcefa3f8); /* 30 */
1001  GG (c, d, a, b, x[ 7], KMD5_S23, 0x676f02d9); /* 31 */
1002  GG (b, c, d, a, x[12], KMD5_S24, 0x8d2a4c8a); /* 32 */
1003 
1004  /* Round 3 */
1005  HH (a, b, c, d, x[ 5], KMD5_S31, 0xfffa3942); /* 33 */
1006  HH (d, a, b, c, x[ 8], KMD5_S32, 0x8771f681); /* 34 */
1007  HH (c, d, a, b, x[11], KMD5_S33, 0x6d9d6122); /* 35 */
1008  HH (b, c, d, a, x[14], KMD5_S34, 0xfde5380c); /* 36 */
1009  HH (a, b, c, d, x[ 1], KMD5_S31, 0xa4beea44); /* 37 */
1010  HH (d, a, b, c, x[ 4], KMD5_S32, 0x4bdecfa9); /* 38 */
1011  HH (c, d, a, b, x[ 7], KMD5_S33, 0xf6bb4b60); /* 39 */
1012  HH (b, c, d, a, x[10], KMD5_S34, 0xbebfbc70); /* 40 */
1013  HH (a, b, c, d, x[13], KMD5_S31, 0x289b7ec6); /* 41 */
1014  HH (d, a, b, c, x[ 0], KMD5_S32, 0xeaa127fa); /* 42 */
1015  HH (c, d, a, b, x[ 3], KMD5_S33, 0xd4ef3085); /* 43 */
1016  HH (b, c, d, a, x[ 6], KMD5_S34, 0x4881d05); /* 44 */
1017  HH (a, b, c, d, x[ 9], KMD5_S31, 0xd9d4d039); /* 45 */
1018  HH (d, a, b, c, x[12], KMD5_S32, 0xe6db99e5); /* 46 */
1019  HH (c, d, a, b, x[15], KMD5_S33, 0x1fa27cf8); /* 47 */
1020  HH (b, c, d, a, x[ 2], KMD5_S34, 0xc4ac5665); /* 48 */
1021 
1022  /* Round 4 */
1023  II (a, b, c, d, x[ 0], KMD5_S41, 0xf4292244); /* 49 */
1024  II (d, a, b, c, x[ 7], KMD5_S42, 0x432aff97); /* 50 */
1025  II (c, d, a, b, x[14], KMD5_S43, 0xab9423a7); /* 51 */
1026  II (b, c, d, a, x[ 5], KMD5_S44, 0xfc93a039); /* 52 */
1027  II (a, b, c, d, x[12], KMD5_S41, 0x655b59c3); /* 53 */
1028  II (d, a, b, c, x[ 3], KMD5_S42, 0x8f0ccc92); /* 54 */
1029  II (c, d, a, b, x[10], KMD5_S43, 0xffeff47d); /* 55 */
1030  II (b, c, d, a, x[ 1], KMD5_S44, 0x85845dd1); /* 56 */
1031  II (a, b, c, d, x[ 8], KMD5_S41, 0x6fa87e4f); /* 57 */
1032  II (d, a, b, c, x[15], KMD5_S42, 0xfe2ce6e0); /* 58 */
1033  II (c, d, a, b, x[ 6], KMD5_S43, 0xa3014314); /* 59 */
1034  II (b, c, d, a, x[13], KMD5_S44, 0x4e0811a1); /* 60 */
1035  II (a, b, c, d, x[ 4], KMD5_S41, 0xf7537e82); /* 61 */
1036  II (d, a, b, c, x[11], KMD5_S42, 0xbd3af235); /* 62 */
1037  II (c, d, a, b, x[ 2], KMD5_S43, 0x2ad7d2bb); /* 63 */
1038  II (b, c, d, a, x[ 9], KMD5_S44, 0xeb86d391); /* 64 */
1039 
1040  m_state[0] += a;
1041  m_state[1] += b;
1042  m_state[2] += c;
1043  m_state[3] += d;
1044 
1045  memset ( static_cast<void *>(x), 0, sizeof(x) );
1046 }
1047 
1048 inline TQ_UINT32 KMD5::rotate_left (TQ_UINT32 x, TQ_UINT32 n)
1049 {
1050  return (x << n) | (x >> (32-n)) ;
1051 }
1052 
1053 inline TQ_UINT32 KMD5::F (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
1054 {
1055  return (x & y) | (~x & z);
1056 }
1057 
1058 inline TQ_UINT32 KMD5::G (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
1059 {
1060  return (x & z) | (y & ~z);
1061 }
1062 
1063 inline TQ_UINT32 KMD5::H (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
1064 {
1065  return x ^ y ^ z;
1066 }
1067 
1068 inline TQ_UINT32 KMD5::I (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
1069 {
1070  return y ^ (x | ~z);
1071 }
1072 
1073 void KMD5::FF ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
1074  TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac )
1075 {
1076  a += F(b, c, d) + x + ac;
1077  a = rotate_left (a, s) +b;
1078 }
1079 
1080 void KMD5::GG ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
1081  TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac)
1082 {
1083  a += G(b, c, d) + x + ac;
1084  a = rotate_left (a, s) +b;
1085 }
1086 
1087 void KMD5::HH ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
1088  TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac )
1089 {
1090  a += H(b, c, d) + x + ac;
1091  a = rotate_left (a, s) +b;
1092 }
1093 
1094 void KMD5::II ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
1095  TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac )
1096 {
1097  a += I(b, c, d) + x + ac;
1098  a = rotate_left (a, s) +b;
1099 }
1100 
1101 
1102 void KMD5::encode ( unsigned char* output, TQ_UINT32 *in, TQ_UINT32 len )
1103 {
1104 #if !defined(WORDS_BIGENDIAN)
1105  memcpy(output, in, len);
1106 
1107 #else
1108  TQ_UINT32 i, j;
1109  for (i = 0, j = 0; j < len; i++, j += 4)
1110  {
1111  output[j] = static_cast<TQ_UINT8>((in[i] & 0xff));
1112  output[j+1] = static_cast<TQ_UINT8>(((in[i] >> 8) & 0xff));
1113  output[j+2] = static_cast<TQ_UINT8>(((in[i] >> 16) & 0xff));
1114  output[j+3] = static_cast<TQ_UINT8>(((in[i] >> 24) & 0xff));
1115  }
1116 #endif
1117 }
1118 
1119 // Decodes in (TQ_UINT8) into output (TQ_UINT32). Assumes len is a
1120 // multiple of 4.
1121 void KMD5::decode (TQ_UINT32 *output, const unsigned char* in, TQ_UINT32 len)
1122 {
1123 #if !defined(WORDS_BIGENDIAN)
1124  memcpy(output, in, len);
1125 
1126 #else
1127  TQ_UINT32 i, j;
1128  for (i = 0, j = 0; j < len; i++, j += 4)
1129  output[i] = static_cast<TQ_UINT32>(in[j]) |
1130  (static_cast<TQ_UINT32>(in[j+1]) << 8) |
1131  (static_cast<TQ_UINT32>(in[j+2]) << 16) |
1132  (static_cast<TQ_UINT32>(in[j+3]) << 24);
1133 #endif
1134 }
1135 
1136 
1137 
1138 /**************************************************************/
1139 
1140 
1141 
1142 /***********************************************************/
1143 
1144 KMD4::KMD4()
1145 {
1146  init();
1147 }
1148 
1149 KMD4::KMD4(const char *in, int len)
1150 {
1151  init();
1152  update(in, len);
1153 }
1154 
1155 KMD4::KMD4(const TQByteArray& in)
1156 {
1157  init();
1158  update( in );
1159 }
1160 
1161 KMD4::KMD4(const TQCString& in)
1162 {
1163  init();
1164  update( in );
1165 }
1166 
1167 void KMD4::update(const TQByteArray& in)
1168 {
1169  update(in.data(), int(in.size()));
1170 }
1171 
1172 void KMD4::update(const TQCString& in)
1173 {
1174  update(in.data(), int(in.length()));
1175 }
1176 
1177 /*
1178  * Update context to reflect the concatenation of another buffer full
1179  * of bytes.
1180  */
1181 void KMD4::update(const unsigned char *in, int len)
1182 {
1183  if (len < 0)
1184  len = tqstrlen(reinterpret_cast<const char*>(in));
1185 
1186  if (!len)
1187  return;
1188 
1189  if (m_finalized) {
1190  kdWarning() << "KMD4::update called after state was finalized!" << endl;
1191  return;
1192  }
1193 
1194  TQ_UINT32 t;
1195 
1196  /* Update bitcount */
1197 
1198  t = m_count[0];
1199  if ((m_count[0] = t + ((TQ_UINT32) len << 3)) < t)
1200  m_count[1]++; /* Carry from low to high */
1201  m_count[1] += len >> 29;
1202 
1203  t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
1204 
1205  /* Handle any leading odd-sized chunks */
1206 
1207  if (t)
1208  {
1209  TQ_UINT8 *p = &m_buffer[ t ];
1210 
1211  t = 64 - t;
1212  if ((TQ_UINT32)len < t)
1213  {
1214  memcpy (p, in, len);
1215  return;
1216  }
1217  memcpy (p, in, t);
1218  byteReverse (m_buffer, 16);
1219  transform (m_state, (TQ_UINT32*) m_buffer);
1220  in += t;
1221  len -= t;
1222  }
1223  /* Process data in 64-byte chunks */
1224 
1225  while (len >= 64)
1226  {
1227  memcpy (m_buffer, in, 64);
1228  byteReverse (m_buffer, 16);
1229  transform (m_state, (TQ_UINT32 *) m_buffer);
1230  in += 64;
1231  len -= 64;
1232  }
1233 
1234  /* Handle any remaining bytes of data. */
1235 
1236  memcpy (m_buffer, in, len);
1237 }
1238 
1239 bool KMD4::update(TQIODevice& file)
1240 {
1241  char buffer[1024];
1242  int len;
1243 
1244  while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
1245  update(buffer, len);
1246 
1247  return file.atEnd();
1248 }
1249 
1250 /*
1251  * Final wrapup - pad to 64-byte boundary with the bit pattern
1252  * 1 0* (64-bit count of bits processed, MSB-first)
1253  */
1254 void KMD4::finalize()
1255 {
1256  unsigned int count;
1257  unsigned char *p;
1258 
1259  /* Compute number of bytes mod 64 */
1260  count = (m_count[0] >> 3) & 0x3F;
1261 
1262  /* Set the first char of padding to 0x80. This is safe since there is
1263  always at least one byte free */
1264  p = m_buffer + count;
1265  *p++ = 0x80;
1266 
1267  /* Bytes of padding needed to make 64 bytes */
1268  count = 64 - 1 - count;
1269 
1270  /* Pad out to 56 mod 64 */
1271  if (count < 8)
1272  {
1273  /* Two lots of padding: Pad the first block to 64 bytes */
1274  memset (p, 0, count);
1275  byteReverse (m_buffer, 16);
1276  transform (m_state, (TQ_UINT32*) m_buffer);
1277 
1278  /* Now fill the next block with 56 bytes */
1279  memset (m_buffer, 0, 56);
1280  }
1281  else
1282  {
1283  /* Pad block to 56 bytes */
1284  memset (p, 0, count - 8);
1285  }
1286  byteReverse (m_buffer, 14);
1287 
1288  /* Append length in bits and transform */
1289  ((TQ_UINT32 *) m_buffer)[14] = m_count[0];
1290  ((TQ_UINT32 *) m_buffer)[15] = m_count[1];
1291 
1292  transform (m_state, (TQ_UINT32 *) m_buffer);
1293  byteReverse ((unsigned char *) m_state, 4);
1294 
1295  memcpy (m_digest, m_state, 16);
1296  memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
1297 
1298  m_finalized = true;
1299 }
1300 
1301 bool KMD4::verify( const KMD4::Digest& digest)
1302 {
1303  finalize();
1304  return (0 == memcmp(rawDigest(), digest, sizeof(KMD4::Digest)));
1305 }
1306 
1307 bool KMD4::verify( const TQCString& hexdigest)
1308 {
1309  finalize();
1310  return (0 == strcmp(hexDigest().data(), hexdigest));
1311 }
1312 
1313 const KMD4::Digest& KMD4::rawDigest()
1314 {
1315  finalize();
1316  return m_digest;
1317 }
1318 
1319 void KMD4::rawDigest( KMD4::Digest& bin )
1320 {
1321  finalize();
1322  memcpy( bin, m_digest, 16 );
1323 }
1324 
1325 TQCString KMD4::hexDigest()
1326 {
1327  TQCString s(33);
1328 
1329  finalize();
1330  sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
1331  m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
1332  m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
1333  m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
1334 // kdDebug() << "KMD4::hexDigest() " << s << endl;
1335  return s;
1336 }
1337 
1338 void KMD4::hexDigest(TQCString& s)
1339 {
1340  finalize();
1341  s.resize(33);
1342  sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
1343  m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
1344  m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
1345  m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
1346 }
1347 
1348 TQCString KMD4::base64Digest()
1349 {
1350  TQByteArray ba(16);
1351 
1352  finalize();
1353  memcpy(ba.data(), m_digest, 16);
1354  return KCodecs::base64Encode(ba);
1355 }
1356 
1357 
1358 void KMD4::init()
1359 {
1360  d = 0;
1361  reset();
1362 }
1363 
1364 /*
1365  * Start MD4 accumulation. Set bit count to 0 and buffer to mysterious
1366  * initialization constants.
1367  */
1368 void KMD4::reset()
1369 {
1370  m_finalized = false;
1371 
1372  m_state[0] = 0x67452301;
1373  m_state[1] = 0xefcdab89;
1374  m_state[2] = 0x98badcfe;
1375  m_state[3] = 0x10325476;
1376 
1377  m_count[0] = 0;
1378  m_count[1] = 0;
1379 
1380  memset ( m_buffer, 0, sizeof(*m_buffer));
1381  memset ( m_digest, 0, sizeof(*m_digest));
1382 }
1383 
1384 //#define rotl32(x,n) (((x) << ((TQ_UINT32)(n))) | ((x) >> (32 - (TQ_UINT32)(n))))
1385 
1386 inline TQ_UINT32 KMD4::rotate_left (TQ_UINT32 x, TQ_UINT32 n)
1387 {
1388  return (x << n) | (x >> (32-n)) ;
1389 }
1390 
1391 inline TQ_UINT32 KMD4::F (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
1392 {
1393  return (x & y) | (~x & z);
1394 }
1395 
1396 inline TQ_UINT32 KMD4::G (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
1397 {
1398  return ((x) & (y)) | ((x) & (z)) | ((y) & (z));
1399 }
1400 
1401 inline TQ_UINT32 KMD4::H (TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z)
1402 {
1403  return x ^ y ^ z;
1404 }
1405 
1406 inline void KMD4::FF ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
1407  TQ_UINT32 x, TQ_UINT32 s )
1408 {
1409  a += F(b, c, d) + x;
1410  a = rotate_left (a, s);
1411 }
1412 
1413 inline void KMD4::GG ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
1414  TQ_UINT32 x, TQ_UINT32 s)
1415 {
1416  a += G(b, c, d) + x + (TQ_UINT32)0x5a827999;
1417  a = rotate_left (a, s);
1418 }
1419 
1420 inline void KMD4::HH ( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d,
1421  TQ_UINT32 x, TQ_UINT32 s )
1422 {
1423  a += H(b, c, d) + x + (TQ_UINT32)0x6ed9eba1;
1424  a = rotate_left (a, s);
1425 }
1426 
1427 void KMD4::byteReverse( unsigned char *buf, TQ_UINT32 len )
1428 {
1429 #ifdef WORDS_BIGENDIAN
1430  TQ_UINT32 *b = (TQ_UINT32*) buf;
1431  while ( len > 0 ) {
1432  *b = ((((*b) & 0xff000000) >> 24) | (((*b) & 0x00ff0000) >> 8) |
1433  (((*b) & 0x0000ff00) << 8) | (((*b) & 0x000000ff) << 24));
1434  len--;
1435  b++;
1436  }
1437 #else
1438  Q_UNUSED(buf)
1439  Q_UNUSED(len)
1440 #endif
1441 }
1442 
1443 /*
1444  * The core of the MD4 algorithm
1445  */
1446 void KMD4::transform( TQ_UINT32 buf[4], TQ_UINT32 const in[16] )
1447 {
1448  TQ_UINT32 a, b, c, d;
1449 
1450  a = buf[0];
1451  b = buf[1];
1452  c = buf[2];
1453  d = buf[3];
1454 
1455  FF (a, b, c, d, in[0], 3); /* 1 */
1456  FF (d, a, b, c, in[1], 7); /* 2 */
1457  FF (c, d, a, b, in[2], 11); /* 3 */
1458  FF (b, c, d, a, in[3], 19); /* 4 */
1459  FF (a, b, c, d, in[4], 3); /* 5 */
1460  FF (d, a, b, c, in[5], 7); /* 6 */
1461  FF (c, d, a, b, in[6], 11); /* 7 */
1462  FF (b, c, d, a, in[7], 19); /* 8 */
1463  FF (a, b, c, d, in[8], 3); /* 9 */
1464  FF (d, a, b, c, in[9], 7); /* 10 */
1465  FF (c, d, a, b, in[10], 11); /* 11 */
1466  FF (b, c, d, a, in[11], 19); /* 12 */
1467  FF (a, b, c, d, in[12], 3); /* 13 */
1468  FF (d, a, b, c, in[13], 7); /* 14 */
1469  FF (c, d, a, b, in[14], 11); /* 15 */
1470  FF (b, c, d, a, in[15], 19); /* 16 */
1471 
1472  GG (a, b, c, d, in[0], 3); /* 17 */
1473  GG (d, a, b, c, in[4], 5); /* 18 */
1474  GG (c, d, a, b, in[8], 9); /* 19 */
1475  GG (b, c, d, a, in[12], 13); /* 20 */
1476  GG (a, b, c, d, in[1], 3); /* 21 */
1477  GG (d, a, b, c, in[5], 5); /* 22 */
1478  GG (c, d, a, b, in[9], 9); /* 23 */
1479  GG (b, c, d, a, in[13], 13); /* 24 */
1480  GG (a, b, c, d, in[2], 3); /* 25 */
1481  GG (d, a, b, c, in[6], 5); /* 26 */
1482  GG (c, d, a, b, in[10], 9); /* 27 */
1483  GG (b, c, d, a, in[14], 13); /* 28 */
1484  GG (a, b, c, d, in[3], 3); /* 29 */
1485  GG (d, a, b, c, in[7], 5); /* 30 */
1486  GG (c, d, a, b, in[11], 9); /* 31 */
1487  GG (b, c, d, a, in[15], 13); /* 32 */
1488 
1489  HH (a, b, c, d, in[0], 3); /* 33 */
1490  HH (d, a, b, c, in[8], 9); /* 34 */
1491  HH (c, d, a, b, in[4], 11); /* 35 */
1492  HH (b, c, d, a, in[12], 15); /* 36 */
1493  HH (a, b, c, d, in[2], 3); /* 37 */
1494  HH (d, a, b, c, in[10], 9); /* 38 */
1495  HH (c, d, a, b, in[6], 11); /* 39 */
1496  HH (b, c, d, a, in[14], 15); /* 40 */
1497  HH (a, b, c, d, in[1], 3); /* 41 */
1498  HH (d, a, b, c, in[9], 9); /* 42 */
1499  HH (c, d, a, b, in[5], 11); /* 43 */
1500  HH (b, c, d, a, in[13], 15); /* 44 */
1501  HH (a, b, c, d, in[3], 3); /* 45 */
1502  HH (d, a, b, c, in[11], 9); /* 46 */
1503  HH (c, d, a, b, in[7], 11); /* 47 */
1504  HH (b, c, d, a, in[15], 15); /* 48 */
1505 
1506 
1507  buf[0] += a;
1508  buf[1] += b;
1509  buf[2] += c;
1510  buf[3] += d;
1511 }
KMD4::hexDigest
TQCString hexDigest()
Returns the value of the calculated message digest in a hexadecimal representation.
Definition: kmdcodec.cpp:1325
KCodecs::quotedPrintableDecode
static TQCString quotedPrintableDecode(const TQByteArray &in)
Decodes a quoted-printable encoded data.
Definition: kmdcodec.cpp:288
KCodecs::uuencode
static TQCString uuencode(const TQByteArray &in)
Encodes the given data using the uuencode algorithm.
Definition: kmdcodec.cpp:564
KCodecs::base64Decode
static TQCString base64Decode(const TQByteArray &in)
Decodes the given data that was encoded using the base64 algorithm.
Definition: kmdcodec.cpp:462
KCodecs::quotedPrintableEncode
static TQCString quotedPrintableEncode(const TQByteArray &in, bool useCRLF=true)
Encodes the given data using the quoted-printable algorithm.
Definition: kmdcodec.cpp:155
KMD4::transform
void transform(TQ_UINT32 buf[4], TQ_UINT32 const in[16])
Performs the real update work.
Definition: kmdcodec.cpp:1446
KCodecs::uudecode
static TQCString uudecode(const TQByteArray &in)
Decodes the given data using the uudecode algorithm.
Definition: kmdcodec.cpp:661
KMD5::base64Digest
TQCString base64Digest()
Returns the value of the calculated message digest in a base64-encoded representation.
Definition: kmdcodec.cpp:926
KMD4::rawDigest
const Digest & rawDigest()
Definition: kmdcodec.cpp:1313
KMD4::reset
void reset()
Calling this function will reset the calculated message digest.
Definition: kmdcodec.cpp:1368
KMD5::verify
bool verify(const KMD5::Digest &digest)
returns true if the calculated digest for the given message matches the given one.
Definition: kmdcodec.cpp:878
KMD5::update
void update(const char *in, int len=-1)
Updates the message to be digested.
Definition: kmdcodec.h:442
KMD5::rawDigest
const Digest & rawDigest()
Definition: kmdcodec.cpp:890
KMD5::finalize
void finalize()
finalizes the digest
Definition: kmdcodec.cpp:842
KMD5::transform
void transform(const unsigned char buffer[64])
Performs the real update work.
Definition: kmdcodec.cpp:958
KMD4::update
void update(const char *in, int len=-1)
Updates the message to be digested.
Definition: kmdcodec.h:617
KCodecs::base64Encode
static TQCString base64Encode(const TQByteArray &in, bool insertLFs=false)
Encodes the given data using the base64 algorithm.
Definition: kmdcodec.cpp:373
KMD4::finalize
void finalize()
finalizes the digest
Definition: kmdcodec.cpp:1254
KMD5::hexDigest
TQCString hexDigest()
Returns the value of the calculated message digest in a hexadecimal representation.
Definition: kmdcodec.cpp:903
KMD5::reset
void reset()
Calling this function will reset the calculated message digest.
Definition: kmdcodec.cpp:942
KMD4::verify
bool verify(const KMD4::Digest &digest)
returns true if the calculated digest for the given message matches the given one.
Definition: kmdcodec.cpp:1301
KMD4::base64Digest
TQCString base64Digest()
Returns the value of the calculated message digest in a base64-encoded representation.
Definition: kmdcodec.cpp:1348
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583

tdecore

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

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.8.8
This website is maintained by Timothy Pearson.