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

kdecore

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

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.8.3.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |