00001
00002 #include <qstring.h>
00003 #include "qtmd5.h"
00004
00005 typedef unsigned char *POINTER;
00006 typedef unsigned short int UINT2;
00007 typedef unsigned long int UINT4;
00008
00009 typedef struct {
00010 UINT4 state[4];
00011 UINT4 count[2];
00012 unsigned char buffer[64];
00013 } MD5_CTX;
00014
00015 static void MD5Init(MD5_CTX *);
00016 static void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
00017 static void MD5Final(unsigned char [16], MD5_CTX *);
00018 static void MD5Transform(UINT4[4], unsigned char[64]);
00019 static void Encode(unsigned char *, UINT4 *, unsigned int);
00020 static void Decode(UINT4 *, unsigned char *, unsigned int);
00021 static void MD5_memset(POINTER, int, unsigned int);
00022 static void MD5_memcpy(POINTER output,POINTER input,unsigned int len);
00023
00024
00025 enum {
00026 S11 = 7, S12 = 12, S13 = 17, S14 = 22, S21 = 5, S22 = 9, S23 = 14, S24 = 20,
00027 S31 = 4, S32 = 11, S33 = 16, S34 = 23, S41 = 6, S42 = 10, S43 = 15, S44 = 21
00028 };
00029
00030 static unsigned char PADDING[64] = {
00031 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00032 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00033 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00034 };
00035
00036
00037 static inline UINT4 F(UINT4 x, UINT4 y, UINT4 z)
00038 {
00039 return(x & y) |((~x) & z);
00040 }
00041
00042 static inline UINT4 G(UINT4 x, UINT4 y, UINT4 z)
00043 {
00044 return(x & z) |(y &(~z));
00045 }
00046
00047 static inline UINT4 H(UINT4 x, UINT4 y, UINT4 z)
00048 {
00049 return x ^ y ^ z;
00050 }
00051
00052 static inline UINT4 I(UINT4 x, UINT4 y, UINT4 z)
00053 {
00054 return y ^(x |(~z));
00055 }
00056
00057 static inline UINT4 rotateLeft(UINT4 x, UINT4 n)
00058 {
00059 return(x << n) |(x >>(32-(n)));
00060 }
00061
00062
00063
00064 static inline void FF(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
00065 {
00066 a += F(b, c, d) + x + ac;
00067 a = rotateLeft(a, s);
00068 a += b;
00069 }
00070
00071 static inline void GG(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
00072 {
00073 a += G(b, c, d) + x +(UINT4)(ac);
00074 a = rotateLeft(a, s);
00075 a += b;
00076 }
00077
00078 static inline void HH(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
00079 {
00080 a += H(b, c, d) + x +(UINT4)(ac);
00081 a = rotateLeft(a, s);
00082 a += b;
00083 }
00084
00085 static inline void II(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac)
00086 {
00087 a += I(b, c, d) + x +(UINT4)(ac);
00088 a = rotateLeft(a, s);
00089 a += b;
00090 }
00091
00092
00093 static void MD5Init(MD5_CTX *context)
00094 {
00095 context->count[0] = context->count[1] = 0;
00096
00097
00098 context->state[0] = 0x67452301;
00099 context->state[1] = 0xefcdab89;
00100 context->state[2] = 0x98badcfe;
00101 context->state[3] = 0x10325476;
00102 }
00103
00104
00105
00106
00107 static void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen)
00108 {
00109 unsigned int i, index, partLen;
00110
00111 index =(unsigned int)((context->count[0] >> 3) & 0x3F);
00112
00113
00114 if ((context->count[0] +=((UINT4)inputLen << 3)) <((UINT4)inputLen << 3))
00115 context->count[1]++;
00116
00117 context->count[1] +=((UINT4)inputLen >> 29);
00118 partLen = 64 - index;
00119
00120
00121 if (inputLen >= partLen) {
00122 MD5_memcpy((POINTER)&context->buffer[index],(POINTER)input, partLen);
00123 MD5Transform(context->state, context->buffer);
00124 for (i = partLen; i + 63 < inputLen; i += 64)
00125 MD5Transform(context->state, &input[i]);
00126 index = 0;
00127 } else {
00128 i = 0;
00129 }
00130
00131
00132 MD5_memcpy((POINTER)&context->buffer[index],(POINTER)&input[i],
00133 inputLen-i);
00134 }
00135
00136
00137
00138 static void MD5Final(unsigned char digest[16], MD5_CTX *context)
00139 {
00140 unsigned char bits[8];
00141 unsigned int index, padLen;
00142
00143
00144 Encode(bits, context->count, 8);
00145
00146
00147 index =(unsigned int)((context->count[0] >> 3) & 0x3f);
00148 padLen =(index < 56) ?(56 - index) :(120 - index);
00149 MD5Update(context, PADDING, padLen);
00150
00151
00152 MD5Update(context, bits, 8);
00153
00154
00155 Encode(digest, context->state, 16);
00156
00157
00158 MD5_memset((POINTER)context, 0, sizeof(*context));
00159 }
00160
00161
00162 static void MD5Transform(UINT4 state[4], unsigned char block[64])
00163 {
00164 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00165 Decode(x, block, 64);
00166
00167
00168 FF(a, b, c, d, x[ 0], S11, 0xd76aa478);
00169 FF(d, a, b, c, x[ 1], S12, 0xe8c7b756);
00170 FF(c, d, a, b, x[ 2], S13, 0x242070db);
00171 FF(b, c, d, a, x[ 3], S14, 0xc1bdceee);
00172 FF(a, b, c, d, x[ 4], S11, 0xf57c0faf);
00173 FF(d, a, b, c, x[ 5], S12, 0x4787c62a);
00174 FF(c, d, a, b, x[ 6], S13, 0xa8304613);
00175 FF(b, c, d, a, x[ 7], S14, 0xfd469501);
00176 FF(a, b, c, d, x[ 8], S11, 0x698098d8);
00177 FF(d, a, b, c, x[ 9], S12, 0x8b44f7af);
00178 FF(c, d, a, b, x[10], S13, 0xffff5bb1);
00179 FF(b, c, d, a, x[11], S14, 0x895cd7be);
00180 FF(a, b, c, d, x[12], S11, 0x6b901122);
00181 FF(d, a, b, c, x[13], S12, 0xfd987193);
00182 FF(c, d, a, b, x[14], S13, 0xa679438e);
00183 FF(b, c, d, a, x[15], S14, 0x49b40821);
00184
00185
00186 GG(a, b, c, d, x[ 1], S21, 0xf61e2562);
00187 GG(d, a, b, c, x[ 6], S22, 0xc040b340);
00188 GG(c, d, a, b, x[11], S23, 0x265e5a51);
00189 GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
00190 GG(a, b, c, d, x[ 5], S21, 0xd62f105d);
00191 GG(d, a, b, c, x[10], S22, 0x2441453);
00192 GG(c, d, a, b, x[15], S23, 0xd8a1e681);
00193 GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
00194 GG(a, b, c, d, x[ 9], S21, 0x21e1cde6);
00195 GG(d, a, b, c, x[14], S22, 0xc33707d6);
00196 GG(c, d, a, b, x[ 3], S23, 0xf4d50d87);
00197 GG(b, c, d, a, x[ 8], S24, 0x455a14ed);
00198 GG(a, b, c, d, x[13], S21, 0xa9e3e905);
00199 GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8);
00200 GG(c, d, a, b, x[ 7], S23, 0x676f02d9);
00201 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);
00202
00203
00204 HH(a, b, c, d, x[ 5], S31, 0xfffa3942);
00205 HH(d, a, b, c, x[ 8], S32, 0x8771f681);
00206 HH(c, d, a, b, x[11], S33, 0x6d9d6122);
00207 HH(b, c, d, a, x[14], S34, 0xfde5380c);
00208 HH(a, b, c, d, x[ 1], S31, 0xa4beea44);
00209 HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9);
00210 HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60);
00211 HH(b, c, d, a, x[10], S34, 0xbebfbc70);
00212 HH(a, b, c, d, x[13], S31, 0x289b7ec6);
00213 HH(d, a, b, c, x[ 0], S32, 0xeaa127fa);
00214 HH(c, d, a, b, x[ 3], S33, 0xd4ef3085);
00215 HH(b, c, d, a, x[ 6], S34, 0x4881d05);
00216 HH(a, b, c, d, x[ 9], S31, 0xd9d4d039);
00217 HH(d, a, b, c, x[12], S32, 0xe6db99e5);
00218 HH(c, d, a, b, x[15], S33, 0x1fa27cf8);
00219 HH(b, c, d, a, x[ 2], S34, 0xc4ac5665);
00220
00221
00222 II(a, b, c, d, x[ 0], S41, 0xf4292244);
00223 II(d, a, b, c, x[ 7], S42, 0x432aff97);
00224 II(c, d, a, b, x[14], S43, 0xab9423a7);
00225 II(b, c, d, a, x[ 5], S44, 0xfc93a039);
00226 II(a, b, c, d, x[12], S41, 0x655b59c3);
00227 II(d, a, b, c, x[ 3], S42, 0x8f0ccc92);
00228 II(c, d, a, b, x[10], S43, 0xffeff47d);
00229 II(b, c, d, a, x[ 1], S44, 0x85845dd1);
00230 II(a, b, c, d, x[ 8], S41, 0x6fa87e4f);
00231 II(d, a, b, c, x[15], S42, 0xfe2ce6e0);
00232 II(c, d, a, b, x[ 6], S43, 0xa3014314);
00233 II(b, c, d, a, x[13], S44, 0x4e0811a1);
00234 II(a, b, c, d, x[ 4], S41, 0xf7537e82);
00235 II(d, a, b, c, x[11], S42, 0xbd3af235);
00236 II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
00237 II(b, c, d, a, x[ 9], S44, 0xeb86d391);
00238 state[0] += a;
00239 state[1] += b;
00240 state[2] += c;
00241 state[3] += d;
00242
00243
00244 MD5_memset((POINTER)x, 0, sizeof(x));
00245 }
00246
00247
00248
00249 static void Encode(unsigned char *output, UINT4 *input, unsigned int len)
00250 {
00251 unsigned int i, j;
00252 for (i = 0, j = 0; j < len; i++, j += 4) {
00253 output[j] = (unsigned char) (input[i] & 0xff);
00254 output[j+1] = (unsigned char) ((input[i] >> 8) & 0xff);
00255 output[j+2] = (unsigned char) ((input[i] >> 16) & 0xff);
00256 output[j+3] = (unsigned char) ((input[i] >> 24) & 0xff);
00257 }
00258 }
00259
00260
00261
00262 static void Decode(UINT4 *output, unsigned char *input, unsigned int len)
00263 {
00264 unsigned int i, j;
00265 for (i = 0, j = 0; j < len; i++, j += 4)
00266 output[i] =((UINT4)input[j]) |(((UINT4)input[j+1]) << 8) |
00267 (((UINT4)input[j+2]) << 16) |(((UINT4)input[j+3]) << 24);
00268 }
00269
00270
00271 static void MD5_memset(POINTER output, int value, unsigned int len)
00272 {
00273 unsigned int i;
00274 for (i = 0; i < len; i++)
00275 ((char *)output)[i] =(char)value;
00276 }
00277
00278
00279 static void MD5_memcpy(POINTER output,POINTER input,unsigned int len)
00280 {
00281 unsigned int i;
00282 for (i = 0; i < len; i++)
00283 output[i] = input[i];
00284 }
00285
00286 void qtMD5(const QByteArray &src, unsigned char *digest)
00287 {
00288 MD5_CTX context;
00289
00290 MD5Init(&context);
00291 MD5Update(&context, (unsigned char *) src.data(), src.size());
00292 MD5Final(digest, &context);
00293 }
00294
00295 QString qtMD5(const QByteArray &src)
00296 {
00297 unsigned char digest[16];
00298 qtMD5(src, digest);
00299
00300 QString output, tmp;
00301 for (int i = 0; i < 16; ++i)
00302 output += tmp.sprintf("%02x", digest[i]);
00303 return output;
00304 }