kmdcodec.cpp
/*
Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License (LGPL)
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992.
RSA Data Security, Inc. Created 1991. All rights reserved.
The KMD5 class is based on a C++ implementation of
"RSA Data Security, Inc. MD5 Message-Digest Algorithm" by
Mordechai T. Abzug, Copyright (c) 1995. This implementation
passes the test-suite as defined in RFC 1321.
The encoding and decoding utilities in KCodecs with the exception of
quoted-printable are based on the java implementation in HTTPClient
package by Ronald Tschalär Copyright (C) 1996-1999.
The quoted-printable codec as described in RFC 2045, section 6.7. is by
Rik Hemsley (C) 2001.
KMD4 class based on the LGPL code of Copyright (C) 2001 Nikos Mavroyanopoulos
The algorithm is due to Ron Rivest. This code is based on code
written by Colin Plumb in 1993.
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <kdebug.h>
#include "kmdcodec.h"
#define KMD5_S11 7
#define KMD5_S12 12
#define KMD5_S13 17
#define KMD5_S14 22
#define KMD5_S21 5
#define KMD5_S22 9
#define KMD5_S23 14
#define KMD5_S24 20
#define KMD5_S31 4
#define KMD5_S32 11
#define KMD5_S33 16
#define KMD5_S34 23
#define KMD5_S41 6
#define KMD5_S42 10
#define KMD5_S43 15
#define KMD5_S44 21
const char KCodecs::Base64EncMap[64] =
{
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
};
const char KCodecs::Base64DecMap[128] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
};
const char KCodecs::UUEncMap[64] =
{
0x60, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
};
const char KCodecs::UUDecMap[128] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const char KCodecs::hexChars[16] =
{
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
const unsigned int KCodecs::maxQPLineLength = 70;
/******************************** KCodecs ********************************/
// strchr(3) for broken systems.
static int rikFindChar(register const char * _s, const char c)
{
register const char * s = _s;
while (true)
{
if ((0 == *s) || (c == *s)) break; ++s;
if ((0 == *s) || (c == *s)) break; ++s;
if ((0 == *s) || (c == *s)) break; ++s;
if ((0 == *s) || (c == *s)) break; ++s;
}
return s - _s;
}
QCString KCodecs::quotedPrintableEncode(const QByteArray& in, bool useCRLF)
{
QByteArray out;
quotedPrintableEncode (in, out, useCRLF);
return QCString (out.data(), out.size()+1);
}
QCString KCodecs::quotedPrintableEncode(const QCString& str, bool useCRLF)
{
if (str.isEmpty())
return "";
QByteArray in (str.length());
memcpy (in.data(), str.data(), str.length());
return quotedPrintableEncode(in, useCRLF);
}
void KCodecs::quotedPrintableEncode(const QByteArray& in, QByteArray& out, bool useCRLF)
{
out.resize (0);
if (in.isEmpty())
return;
char *cursor;
const char *data;
unsigned int lineLength;
unsigned int pos;
const unsigned int length = in.size();
const unsigned int end = length - 1;
// Reasonable guess for output size when we're encoding
// mostly-ASCII data. It doesn't really matter, because
// the underlying allocation routines are quite efficient,
// but it's nice to have 0 allocations in many cases.
out.resize ((length*12)/10);
cursor = out.data();
data = in.data();
lineLength = 0;
pos = 0;
for (unsigned int i = 0; i < length; i++)
{
unsigned char c (data[i]);
// check if we have to enlarge the output buffer, use
// a safety margin of 16 byte
pos = cursor-out.data();
if (out.size()-pos < 16) {
out.resize(out.size()+4096);
cursor = out.data()+pos;
}
// Plain ASCII chars just go straight out.
if ((c >= 33) && (c <= 126) && ('=' != c))
{
*cursor++ = c;
++lineLength;
}
// Spaces need some thought. We have to encode them at eol (or eof).
else if (' ' == c)
{
if
(
(i >= length)
||
((i < end) && ((useCRLF && ('\r' == data[i + 1]) && ('\n' == data[i + 2]))
||
(!useCRLF && ('\n' == data[i + 1]))))
)
{
*cursor++ = '=';
*cursor++ = '2';
*cursor++ = '0';
lineLength += 3;
}
else
{
*cursor++ = ' ';
++lineLength;
}
}
// If we find a line break, just let it through.
else if ((useCRLF && ('\r' == c) && (i < end) && ('\n' == data[i + 1])) ||
(!useCRLF && ('\n' == c)))
{
lineLength = 0;
if (useCRLF) {
*cursor++ = '\r';
*cursor++ = '\n';
++i;
} else {
*cursor++ = '\n';
}
}
// Anything else is converted to =XX.
else
{
*cursor++ = '=';
*cursor++ = hexChars[c / 16];
*cursor++ = hexChars[c % 16];
lineLength += 3;
}
// If we're approaching the maximum line length, do a soft line break.
if ((lineLength > maxQPLineLength) && (i < end))
{
if (useCRLF) {
*cursor++ = '=';
*cursor++ = '\r';
*cursor++ = '\n';
} else {
*cursor++ = '=';
*cursor++ = '\n';
}
lineLength = 0;
}
}
out.truncate(cursor - out.data());
}
QCString KCodecs::quotedPrintableDecode(const QByteArray & in)
{
QByteArray out;
quotedPrintableDecode (in, out);
return QCString (out.data(), out.size()+1);
}
QCString KCodecs::quotedPrintableDecode(const QCString & str)
{
if (str.isEmpty())
return "";
QByteArray in (str.length());
memcpy (in.data(), str.data(), str.length());
return quotedPrintableDecode (in);
}
void KCodecs::quotedPrintableDecode(const QByteArray& in, QByteArray& out)
{
// clear out the output buffer
out.resize (0);
if (in.isEmpty())
return;
char *cursor;
const char *data;
const unsigned int length = in.size();
data = in.data();
out.resize (length);
cursor = out.data();
for (unsigned int i = 0; i < length; i++)
{
char c(in[i]);
if ('=' == c)
{
if (i < length - 2)
{
char c1 = in[i + 1];
char c2 = in[i + 2];
if (('\n' == c1) || ('\r' == c1 && '\n' == c2))
{
// Soft line break. No output.
if ('\r' == c1)
i += 2; // CRLF line breaks
else
i += 1;
}
else
{
// =XX encoded byte.
int hexChar0 = rikFindChar(hexChars, c1);
int hexChar1 = rikFindChar(hexChars, c2);
if (hexChar0 < 16 && hexChar1 < 16)
{
*cursor++ = char((hexChar0 * 16) | hexChar1);
i += 2;
}
}
}
}
else
{
*cursor++ = c;
}
}
out.truncate(cursor - out.data());
}
QCString KCodecs::base64Encode( const QCString& str, bool insertLFs )
{
if ( str.isEmpty() )
return "";
QByteArray in (str.length());
memcpy( in.data(), str.data(), str.length() );
return base64Encode( in, insertLFs );
}
QCString KCodecs::base64Encode( const QByteArray& in, bool insertLFs )
{
QByteArray out;
base64Encode( in, out, insertLFs );
return QCString( out.data(), out.size()+1 );
}
void KCodecs::base64Encode( const QByteArray& in, QByteArray& out,
bool insertLFs )
{
// clear out the output buffer
out.resize (0);
if ( in.isEmpty() )
return;
unsigned int sidx = 0;
unsigned int didx = 0;
const char* data = in.data();
const unsigned int len = in.size();
unsigned int out_len = ((len+2)/3)*4;
// Deal with the 76 characters or less per
// line limit specified in RFC 2045 on a
// pre request basis.
insertLFs = (insertLFs && out_len > 76);
if ( insertLFs )
out_len += ((out_len-1)/76);
int count = 0;
out.resize( out_len );
// 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
if ( len > 1 )
{
while (sidx < len-2)
{
if ( insertLFs )
{
if ( count && (count%76) == 0 )
out[didx++] = '\n';
count += 4;
}
out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
(data[sidx] << 4) & 077];
out[didx++] = Base64EncMap[(data[sidx+2] >> 6) & 003 |
(data[sidx+1] << 2) & 077];
out[didx++] = Base64EncMap[data[sidx+2] & 077];
sidx += 3;
}
}
if (sidx < len)
{
if ( insertLFs && (count > 0) && (count%76) == 0 )
out[didx++] = '\n';
out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
if (sidx < len-1)
{
out[didx++] = Base64EncMap[(data[sidx+1] >> 4) & 017 |
(data[sidx] << 4) & 077];
out[didx++] = Base64EncMap[(data[sidx+1] << 2) & 077];
}
else
{
out[didx++] = Base64EncMap[(data[sidx] << 4) & 077];
}
}
// Add padding
while (didx < out.size())
{
out[didx] = '=';
didx++;
}
}
QCString KCodecs::base64Decode( const QCString& str )
{
if ( str.isEmpty() )
return "";
QByteArray in( str.length() );
memcpy( in.data(), str.data(), str.length() );
return base64Decode( in );
}
QCString KCodecs::base64Decode( const QByteArray& in )
{
QByteArray out;
base64Decode( in, out );
return QCString( out.data(), out.size()+1 );
}
void KCodecs::base64Decode( const QByteArray& in, QByteArray& out )
{
out.resize(0);
if ( in.isEmpty() )
return;
unsigned int count = 0;
unsigned int len = in.size(), tail = len;
const char* data = in.data();
// Deal with possible *nix "BEGIN" marker!!
while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
data[count] == '\t' || data[count] == ' ') )
count++;
if ( count == len )
return;
if ( strncasecmp(data+count, "begin", 5) == 0 )
{
count += 5;
while ( count < len && data[count] != '\n' && data[count] != '\r' )
count++;
while ( count < len && (data[count] == '\n' || data[count] == '\r') )
count ++;
data += count;
tail = (len -= count);
}
// Find the tail end of the actual encoded data even if
// there is/are trailing CR and/or LF.
while ( tail > 0
&& ( data[tail-1] == '=' || data[tail-1] == '\n' || data[tail-1] == '\r' ) )
if ( data[--tail] != '=' ) len = tail;
unsigned int outIdx = 0;
out.resize( (count=len) );
for (unsigned int idx = 0; idx < count; idx++)
{
// Adhere to RFC 2045 and ignore characters
// that are not part of the encoding table.
unsigned char ch = data[idx];
if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||
(ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
{
out[outIdx++] = Base64DecMap[ch];
}
else
{
len--;
tail--;
}
}
// kdDebug() << "Tail size = " << tail << ", Length size = " << len << endl;
// 4-byte to 3-byte conversion
len = (tail>(len/4)) ? tail-(len/4) : 0;
unsigned int sidx = 0, didx = 0;
if ( len > 1 )
{
while (didx < len-2)
{
out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077));
sidx += 4;
didx += 3;
}
}
if (didx < len)
out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
if (++didx < len )
out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
// Resize the output buffer
if ( len == 0 || len < out.size() )
out.resize(len);
}
QCString KCodecs::uuencode( const QCString& str )
{
if ( str.isEmpty() )
return "";
QByteArray in;
in.resize( str.length() );
memcpy( in.data(), str.data(), str.length() );
return uuencode( in );
}
QCString KCodecs::uuencode( const QByteArray& in )
{
QByteArray out;
uuencode( in, out );
return QCString( out.data(), out.size()+1 );
}
void KCodecs::uuencode( const QByteArray& in, QByteArray& out )
{
out.resize( 0 );
if( in.isEmpty() )
return;
unsigned int sidx = 0;
unsigned int didx = 0;
unsigned int line_len = 45;
const char nl[] = "\n";
const char* data = in.data();
const unsigned int nl_len = strlen(nl);
const unsigned int len = in.size();
out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );
// split into lines, adding line-length and line terminator
while (sidx+line_len < len)
{
// line length
out[didx++] = UUEncMap[line_len];
// 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)
{
out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
(data[sidx] << 4) & 077];
out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
(data[sidx+1] << 2) & 077];
out[didx++] = UUEncMap[data[sidx+2] & 077];
}
// line terminator
//for (unsigned int idx=0; idx < nl_len; idx++)
//out[didx++] = nl[idx];
memcpy(out.data()+didx, nl, nl_len);
didx += nl_len;
}
// line length
out[didx++] = UUEncMap[len-sidx];
// 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
while (sidx+2 < len)
{
out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
(data[sidx] << 4) & 077];
out[didx++] = UUEncMap[(data[sidx+2] >> 6) & 003 |
(data[sidx+1] << 2) & 077];
out[didx++] = UUEncMap[data[sidx+2] & 077];
sidx += 3;
}
if (sidx < len-1)
{
out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
out[didx++] = UUEncMap[(data[sidx+1] >> 4) & 017 |
(data[sidx] << 4) & 077];
out[didx++] = UUEncMap[(data[sidx+1] << 2) & 077];
out[didx++] = UUEncMap[0];
}
else if (sidx < len)
{
out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
out[didx++] = UUEncMap[(data[sidx] << 4) & 077];
out[didx++] = UUEncMap[0];
out[didx++] = UUEncMap[0];
}
// line terminator
memcpy(out.data()+didx, nl, nl_len);
didx += nl_len;
// sanity check
if ( didx != out.size() )
out.resize( 0 );
}
QCString KCodecs::uudecode( const QCString& str )
{
if ( str.isEmpty() )
return "";
QByteArray in;
in.resize( str.length() );
memcpy( in.data(), str.data(), str.length() );
return uudecode( in );
}
QCString KCodecs::uudecode( const QByteArray& in )
{
QByteArray out;
uudecode( in, out );
return QCString( out.data(), out.size()+1 );
}
void KCodecs::uudecode( const QByteArray& in, QByteArray& out )
{
out.resize( 0 );
if( in.isEmpty() )
return;
unsigned int sidx = 0;
unsigned int didx = 0;
unsigned int len = in.size();
unsigned int line_len, end;
const char* data = in.data();
// Deal with *nix "BEGIN"/"END" separators!!
unsigned int count = 0;
while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
data[count] == '\t' || data[count] == ' ') )
count ++;
bool hasLF = false;
if ( strncasecmp( data+count, "begin", 5) == 0 )
{
count += 5;
while ( count < len && data[count] != '\n' && data[count] != '\r' )
count ++;
while ( count < len && (data[count] == '\n' || data[count] == '\r') )
count ++;
data += count;
len -= count;
hasLF = true;
}
out.resize( len/4*3 );
while ( sidx < len )
{
// get line length (in number of encoded octets)
line_len = UUDecMap[ (unsigned char) data[sidx++]];
// ascii printable to 0-63 and 4-byte to 3-byte conversion
end = didx+line_len;
char A, B, C, D;
if (end > 2) {
while (didx < end-2)
{
A = UUDecMap[(unsigned char) data[sidx]];
B = UUDecMap[(unsigned char) data[sidx+1]];
C = UUDecMap[(unsigned char) data[sidx+2]];
D = UUDecMap[(unsigned char) data[sidx+3]];
out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
out[didx++] = ( ((C << 6) & 255) | (D & 077) );
sidx += 4;
}
}
if (didx < end)
{
A = UUDecMap[(unsigned char) data[sidx]];
B = UUDecMap[(unsigned char) data[sidx+1]];
out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
}
if (didx < end)
{
B = UUDecMap[(unsigned char) data[sidx+1]];
C = UUDecMap[(unsigned char) data[sidx+2]];
out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
}
// skip padding
while (sidx < len && data[sidx] != '\n' && data[sidx] != '\r')
sidx++;
// skip end of line
while (sidx < len && (data[sidx] == '\n' || data[sidx] == '\r'))
sidx++;
// skip the "END" separator when present.
if ( hasLF && strncasecmp( data+sidx, "end", 3) == 0 )
break;
}
if ( didx < out.size() )
out.resize( didx );
}
/******************************** KMD5 ********************************/
KMD5::KMD5()
{
init();
}
KMD5::KMD5(const char *in, int len)
{
init();
update(in, len);
}
KMD5::KMD5(const QByteArray& in)
{
init();
update( in );
}
KMD5::KMD5(const QCString& in)
{
init();
update( in );
}
void KMD5::update(const QByteArray& in)
{
update(in.data(), int(in.size()));
}
void KMD5::update(const QCString& in)
{
update(in.data(), int(in.length()));
}
void KMD5::update(const unsigned char* in, int len)
{
if (len < 0)
len = qstrlen(reinterpret_cast<const char*>(in));
if (!len)
return;
if (m_finalized) {
kdWarning() << "KMD5::update called after state was finalized!" << endl;
return;
}
Q_UINT32 in_index;
Q_UINT32 buffer_index;
Q_UINT32 buffer_space;
Q_UINT32 in_length = static_cast<Q_UINT32>( len );
buffer_index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3F);
if ( (m_count[0] += (in_length << 3))<(in_length << 3) )
m_count[1]++;
m_count[1] += (in_length >> 29);
buffer_space = 64 - buffer_index;
if (in_length >= buffer_space)
{
memcpy (m_buffer + buffer_index, in, buffer_space);
transform (m_buffer);
for (in_index = buffer_space; in_index + 63 < in_length;
in_index += 64)
transform (reinterpret_cast<const unsigned char*>(in+in_index));
buffer_index = 0;
}
else
in_index=0;
memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);
}
bool KMD5::update(QIODevice& file)
{
char buffer[1024];
int len;
while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
update(buffer, len);
return file.atEnd();
}
void KMD5::finalize ()
{
if (m_finalized) return;
Q_UINT8 bits[8];
Q_UINT32 index, padLen;
static const unsigned char PADDING[64]=
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
encode (bits, m_count, 8);
//memcpy( bits, m_count, 8 );
// Pad out to 56 mod 64.
index = static_cast<Q_UINT32>((m_count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
update (reinterpret_cast<const char*>(PADDING), padLen);
// Append length (before padding)
update (reinterpret_cast<const char*>(bits), 8);
// Store state in digest
encode (m_digest, m_state, 16);
//memcpy( m_digest, m_state, 16 );
// Fill sensitive information with zero's
memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
m_finalized = true;
}
bool KMD5::verify( const KMD5::Digest& digest)
{
finalize();
return (0 == memcmp(rawDigest(), digest, sizeof(KMD5::Digest)));
}
bool KMD5::verify( const QCString& hexdigest)
{
finalize();
return (0 == strcmp(hexDigest().data(), hexdigest));
}
const KMD5::Digest& KMD5::rawDigest()
{
finalize();
return m_digest;
}
void KMD5::rawDigest( KMD5::Digest& bin )
{
finalize();
memcpy( bin, m_digest, 16 );
}
QCString KMD5::hexDigest()
{
QCString s(33);
finalize();
sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
return s;
}
void KMD5::hexDigest(QCString& s)
{
finalize();
s.resize(33);
sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
}
QCString KMD5::base64Digest()
{
QByteArray ba(16);
finalize();
memcpy(ba.data(), m_digest, 16);
return KCodecs::base64Encode(ba);
}
void KMD5::init()
{
d = 0;
reset();
}
void KMD5::reset()
{
m_finalized = false;
m_count[0] = 0;
m_count[1] = 0;
m_state[0] = 0x67452301;
m_state[1] = 0xefcdab89;
m_state[2] = 0x98badcfe;
m_state[3] = 0x10325476;
memset ( m_buffer, 0, sizeof(*m_buffer));
memset ( m_digest, 0, sizeof(*m_digest));
}
void KMD5::transform( const unsigned char block[64] )
{
Q_UINT32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];
decode (x, block, 64);
//memcpy( x, block, 64 );
Q_ASSERT(!m_finalized); // not just a user error, since the method is private
/* Round 1 */
FF (a, b, c, d, x[ 0], KMD5_S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], KMD5_S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], KMD5_S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], KMD5_S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], KMD5_S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], KMD5_S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], KMD5_S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], KMD5_S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], KMD5_S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], KMD5_S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], KMD5_S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], KMD5_S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], KMD5_S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], KMD5_S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], KMD5_S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], KMD5_S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], KMD5_S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], KMD5_S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], KMD5_S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], KMD5_S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], KMD5_S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], KMD5_S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], KMD5_S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], KMD5_S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], KMD5_S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], KMD5_S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], KMD5_S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], KMD5_S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], KMD5_S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], KMD5_S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], KMD5_S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], KMD5_S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], KMD5_S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], KMD5_S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], KMD5_S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], KMD5_S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], KMD5_S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], KMD5_S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], KMD5_S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], KMD5_S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], KMD5_S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], KMD5_S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], KMD5_S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], KMD5_S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], KMD5_S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], KMD5_S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], KMD5_S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], KMD5_S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], KMD5_S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], KMD5_S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], KMD5_S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], KMD5_S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], KMD5_S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], KMD5_S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], KMD5_S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], KMD5_S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], KMD5_S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], KMD5_S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], KMD5_S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], KMD5_S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], KMD5_S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], KMD5_S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], KMD5_S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], KMD5_S44, 0xeb86d391); /* 64 */
m_state[0] += a;
m_state[1] += b;
m_state[2] += c;
m_state[3] += d;
memset ( static_cast<void *>(x), 0, sizeof(x) );
}
inline Q_UINT32 KMD5::rotate_left (Q_UINT32 x, Q_UINT32 n)
{
return (x << n) | (x >> (32-n)) ;
}
inline Q_UINT32 KMD5::F (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
{
return (x & y) | (~x & z);
}
inline Q_UINT32 KMD5::G (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
{
return (x & z) | (y & ~z);
}
inline Q_UINT32 KMD5::H (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
{
return x ^ y ^ z;
}
inline Q_UINT32 KMD5::I (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
{
return y ^ (x | ~z);
}
void KMD5::FF ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
{
a += F(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
void KMD5::GG ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac)
{
a += G(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
void KMD5::HH ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
{
a += H(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
void KMD5::II ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
Q_UINT32 x, Q_UINT32 s, Q_UINT32 ac )
{
a += I(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
void KMD5::encode ( unsigned char* output, Q_UINT32 *in, Q_UINT32 len )
{
#if !defined(WORDS_BIGENDIAN)
memcpy(output, in, len);
#else
Q_UINT32 i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
output[j] = static_cast<Q_UINT8>((in[i] & 0xff));
output[j+1] = static_cast<Q_UINT8>(((in[i] >> 8) & 0xff));
output[j+2] = static_cast<Q_UINT8>(((in[i] >> 16) & 0xff));
output[j+3] = static_cast<Q_UINT8>(((in[i] >> 24) & 0xff));
}
#endif
}
// Decodes in (Q_UINT8) into output (Q_UINT32). Assumes len is a
// multiple of 4.
void KMD5::decode (Q_UINT32 *output, const unsigned char* in, Q_UINT32 len)
{
#if !defined(WORDS_BIGENDIAN)
memcpy(output, in, len);
#else
Q_UINT32 i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = static_cast<Q_UINT32>(in[j]) |
(static_cast<Q_UINT32>(in[j+1]) << 8) |
(static_cast<Q_UINT32>(in[j+2]) << 16) |
(static_cast<Q_UINT32>(in[j+3]) << 24);
#endif
}
/**************************************************************/
/***********************************************************/
KMD4::KMD4()
{
init();
}
KMD4::KMD4(const char *in, int len)
{
init();
update(in, len);
}
KMD4::KMD4(const QByteArray& in)
{
init();
update( in );
}
KMD4::KMD4(const QCString& in)
{
init();
update( in );
}
void KMD4::update(const QByteArray& in)
{
update(in.data(), int(in.size()));
}
void KMD4::update(const QCString& in)
{
update(in.data(), int(in.length()));
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void KMD4::update(const unsigned char *in, int len)
{
if (len < 0)
len = qstrlen(reinterpret_cast<const char*>(in));
if (!len)
return;
if (m_finalized) {
kdWarning() << "KMD4::update called after state was finalized!" << endl;
return;
}
Q_UINT32 t;
/* Update bitcount */
t = m_count[0];
if ((m_count[0] = t + ((Q_UINT32) len << 3)) < t)
m_count[1]++; /* Carry from low to high */
m_count[1] += len >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if (t)
{
Q_UINT8 *p = &m_buffer[ t ];
t = 64 - t;
if ((Q_UINT32)len < t)
{
memcpy (p, in, len);
return;
}
memcpy (p, in, t);
byteReverse (m_buffer, 16);
transform (m_state, (Q_UINT32*) m_buffer);
in += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64)
{
memcpy (m_buffer, in, 64);
byteReverse (m_buffer, 16);
transform (m_state, (Q_UINT32 *) m_buffer);
in += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy (m_buffer, in, len);
}
bool KMD4::update(QIODevice& file)
{
char buffer[1024];
int len;
while ((len=file.readBlock(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
update(buffer, len);
return file.atEnd();
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void KMD4::finalize()
{
unsigned int count;
unsigned char *p;
/* Compute number of bytes mod 64 */
count = (m_count[0] >> 3) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = m_buffer + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8)
{
/* Two lots of padding: Pad the first block to 64 bytes */
memset (p, 0, count);
byteReverse (m_buffer, 16);
transform (m_state, (Q_UINT32*) m_buffer);
/* Now fill the next block with 56 bytes */
memset (m_buffer, 0, 56);
}
else
{
/* Pad block to 56 bytes */
memset (p, 0, count - 8);
}
byteReverse (m_buffer, 14);
/* Append length in bits and transform */
((Q_UINT32 *) m_buffer)[14] = m_count[0];
((Q_UINT32 *) m_buffer)[15] = m_count[1];
transform (m_state, (Q_UINT32 *) m_buffer);
byteReverse ((unsigned char *) m_state, 4);
memcpy (m_digest, m_state, 16);
memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
m_finalized = true;
}
bool KMD4::verify( const KMD4::Digest& digest)
{
finalize();
return (0 == memcmp(rawDigest(), digest, sizeof(KMD4::Digest)));
}
bool KMD4::verify( const QCString& hexdigest)
{
finalize();
return (0 == strcmp(hexDigest().data(), hexdigest));
}
const KMD4::Digest& KMD4::rawDigest()
{
finalize();
return m_digest;
}
void KMD4::rawDigest( KMD4::Digest& bin )
{
finalize();
memcpy( bin, m_digest, 16 );
}
QCString KMD4::hexDigest()
{
QCString s(33);
finalize();
sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
// kdDebug() << "KMD4::hexDigest() " << s << endl;
return s;
}
void KMD4::hexDigest(QCString& s)
{
finalize();
s.resize(33);
sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
}
QCString KMD4::base64Digest()
{
QByteArray ba(16);
finalize();
memcpy(ba.data(), m_digest, 16);
return KCodecs::base64Encode(ba);
}
void KMD4::init()
{
d = 0;
reset();
}
/*
* Start MD4 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void KMD4::reset()
{
m_finalized = false;
m_state[0] = 0x67452301;
m_state[1] = 0xefcdab89;
m_state[2] = 0x98badcfe;
m_state[3] = 0x10325476;
m_count[0] = 0;
m_count[1] = 0;
memset ( m_buffer, 0, sizeof(*m_buffer));
memset ( m_digest, 0, sizeof(*m_digest));
}
//#define rotl32(x,n) (((x) << ((Q_UINT32)(n))) | ((x) >> (32 - (Q_UINT32)(n))))
inline Q_UINT32 KMD4::rotate_left (Q_UINT32 x, Q_UINT32 n)
{
return (x << n) | (x >> (32-n)) ;
}
inline Q_UINT32 KMD4::F (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
{
return (x & y) | (~x & z);
}
inline Q_UINT32 KMD4::G (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
{
return ((x) & (y)) | ((x) & (z)) | ((y) & (z));
}
inline Q_UINT32 KMD4::H (Q_UINT32 x, Q_UINT32 y, Q_UINT32 z)
{
return x ^ y ^ z;
}
inline void KMD4::FF ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
Q_UINT32 x, Q_UINT32 s )
{
a += F(b, c, d) + x;
a = rotate_left (a, s);
}
inline void KMD4::GG ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
Q_UINT32 x, Q_UINT32 s)
{
a += G(b, c, d) + x + (Q_UINT32)0x5a827999;
a = rotate_left (a, s);
}
inline void KMD4::HH ( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d,
Q_UINT32 x, Q_UINT32 s )
{
a += H(b, c, d) + x + (Q_UINT32)0x6ed9eba1;
a = rotate_left (a, s);
}
void KMD4::byteReverse( unsigned char *buf, Q_UINT32 len )
{
#ifdef WORDS_BIGENDIAN
Q_UINT32 *b = (Q_UINT32*) buf;
while ( len > 0 ) {
*b = ((((*b) & 0xff000000) >> 24) | (((*b) & 0x00ff0000) >> 8) |
(((*b) & 0x0000ff00) << 8) | (((*b) & 0x000000ff) << 24));
len--;
b++;
}
#else
Q_UNUSED(buf)
Q_UNUSED(len)
#endif
}
/*
* The core of the MD4 algorithm
*/
void KMD4::transform( Q_UINT32 buf[4], Q_UINT32 const in[16] )
{
Q_UINT32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
FF (a, b, c, d, in[0], 3); /* 1 */
FF (d, a, b, c, in[1], 7); /* 2 */
FF (c, d, a, b, in[2], 11); /* 3 */
FF (b, c, d, a, in[3], 19); /* 4 */
FF (a, b, c, d, in[4], 3); /* 5 */
FF (d, a, b, c, in[5], 7); /* 6 */
FF (c, d, a, b, in[6], 11); /* 7 */
FF (b, c, d, a, in[7], 19); /* 8 */
FF (a, b, c, d, in[8], 3); /* 9 */
FF (d, a, b, c, in[9], 7); /* 10 */
FF (c, d, a, b, in[10], 11); /* 11 */
FF (b, c, d, a, in[11], 19); /* 12 */
FF (a, b, c, d, in[12], 3); /* 13 */
FF (d, a, b, c, in[13], 7); /* 14 */
FF (c, d, a, b, in[14], 11); /* 15 */
FF (b, c, d, a, in[15], 19); /* 16 */
GG (a, b, c, d, in[0], 3); /* 17 */
GG (d, a, b, c, in[4], 5); /* 18 */
GG (c, d, a, b, in[8], 9); /* 19 */
GG (b, c, d, a, in[12], 13); /* 20 */
GG (a, b, c, d, in[1], 3); /* 21 */
GG (d, a, b, c, in[5], 5); /* 22 */
GG (c, d, a, b, in[9], 9); /* 23 */
GG (b, c, d, a, in[13], 13); /* 24 */
GG (a, b, c, d, in[2], 3); /* 25 */
GG (d, a, b, c, in[6], 5); /* 26 */
GG (c, d, a, b, in[10], 9); /* 27 */
GG (b, c, d, a, in[14], 13); /* 28 */
GG (a, b, c, d, in[3], 3); /* 29 */
GG (d, a, b, c, in[7], 5); /* 30 */
GG (c, d, a, b, in[11], 9); /* 31 */
GG (b, c, d, a, in[15], 13); /* 32 */
HH (a, b, c, d, in[0], 3); /* 33 */
HH (d, a, b, c, in[8], 9); /* 34 */
HH (c, d, a, b, in[4], 11); /* 35 */
HH (b, c, d, a, in[12], 15); /* 36 */
HH (a, b, c, d, in[2], 3); /* 37 */
HH (d, a, b, c, in[10], 9); /* 38 */
HH (c, d, a, b, in[6], 11); /* 39 */
HH (b, c, d, a, in[14], 15); /* 40 */
HH (a, b, c, d, in[1], 3); /* 41 */
HH (d, a, b, c, in[9], 9); /* 42 */
HH (c, d, a, b, in[5], 11); /* 43 */
HH (b, c, d, a, in[13], 15); /* 44 */
HH (a, b, c, d, in[3], 3); /* 45 */
HH (d, a, b, c, in[11], 9); /* 46 */
HH (c, d, a, b, in[7], 11); /* 47 */
HH (b, c, d, a, in[15], 15); /* 48 */
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
KMD4::transform
void transform(Q_UINT32 buf[4], Q_UINT32 const in[16])
Performs the real update work.
Definition: kmdcodec.cpp:1445
KCodecs::uuencode
static QCString uuencode(const QByteArray &in)
Encodes the given data using the uuencode algorithm.
Definition: kmdcodec.cpp:563
KMD4::rawDigest
const Digest & rawDigest()
Definition: kmdcodec.cpp:1312
KCodecs::uudecode
static QCString uudecode(const QByteArray &in)
Decodes the given data using the uudecode algorithm.
Definition: kmdcodec.cpp:660
KMD4::reset
void reset()
Calling this function will reset the calculated message digest.
Definition: kmdcodec.cpp:1367
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:877
KCodecs::base64Decode
static QCString base64Decode(const QByteArray &in)
Decodes the given data that was encoded using the base64 algorithm.
Definition: kmdcodec.cpp:461
KMD5::base64Digest
QCString base64Digest()
Returns the value of the calculated message digest in a base64-encoded representation.
Definition: kmdcodec.cpp:925
KMD5::hexDigest
QCString hexDigest()
Returns the value of the calculated message digest in a hexadecimal representation.
Definition: kmdcodec.cpp:902
KMD5::update
void update(const char *in, int len=-1)
Updates the message to be digested.
Definition: kmdcodec.h:442
KCodecs::quotedPrintableEncode
static QCString quotedPrintableEncode(const QByteArray &in, bool useCRLF=true)
Encodes the given data using the quoted-printable algorithm.
Definition: kmdcodec.cpp:154
KMD5::rawDigest
const Digest & rawDigest()
Definition: kmdcodec.cpp:889
KCodecs::quotedPrintableDecode
static QCString quotedPrintableDecode(const QByteArray &in)
Decodes a quoted-printable encoded data.
Definition: kmdcodec.cpp:287
KCodecs::base64Encode
static QCString base64Encode(const QByteArray &in, bool insertLFs=false)
Encodes the given data using the base64 algorithm.
Definition: kmdcodec.cpp:372
KMD5::finalize
void finalize()
finalizes the digest
Definition: kmdcodec.cpp:841
KMD5::transform
void transform(const unsigned char buffer[64])
Performs the real update work.
Definition: kmdcodec.cpp:957
KMD4::update
void update(const char *in, int len=-1)
Updates the message to be digested.
Definition: kmdcodec.h:617
KMD4::finalize
void finalize()
finalizes the digest
Definition: kmdcodec.cpp:1253
KMD5::reset
void reset()
Calling this function will reset the calculated message digest.
Definition: kmdcodec.cpp:941
KMD4::hexDigest
QCString hexDigest()
Returns the value of the calculated message digest in a hexadecimal representation.
Definition: kmdcodec.cpp:1324
KMD4::base64Digest
QCString base64Digest()
Returns the value of the calculated message digest in a base64-encoded representation.
Definition: kmdcodec.cpp:1347
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:1300
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583

KDE Home | KDE Accessibility Home | Description of Access Keys