现在的位置: 首页 > 综合 > 正文

MD5加密算法的实现

2012年11月27日 ⁄ 综合 ⁄ 共 5530字 ⁄ 字号 评论关闭

MD5加密算法的实现

以下是QtMD5加密算法的实现:

/*

 * This code implements the MD5 message-digest algorithm.

 * The algorithm is due to Ron Rivest.  This code was

 * written by Colin Plumb in 1993, no copyright is claimed.

 * This code is in the public domain; do with it what you wish.

 *

 * Equivalent code is available from RSA Data Security, Inc.

 * This code has been tested against that, and is equivalent,

 * except that you don't need to include two pages of legalese

 * with every copy.

 *

 * To compute the message digest of a chunk of bytes, declare an

 * MD5Context structure, pass it to MD5Init, call MD5Update as

 * needed on buffers full of bytes, and then call MD5Final, which

 * will fill a supplied 16-byte array with the digest.

 *

 * Changed so as no longer to depend on Colin Plumb's `usual.h' header

 * definitions; now uses stuff from dpkg's config.h.

 *  - Ian Jackson <ian@chiark.greenend.org.uk>.

 * Still in the public domain.

 */

static void

byteSwap(UWORD32 *buf, unsigned words)

{

        const quint32 byteOrderTest = 0x1;

        if (((char *)&byteOrderTest)[0] == 0) {

            md5byte *p = (md5byte *)buf;

 

            do {

                *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |

                    ((unsigned)p[1] << 8 | p[0]);

                p += 4;

            } while (--words);

        }

}

 

/*

 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious

 * initialization constants.

 */

static void

MD5Init(struct MD5Context *ctx)

{

      ctx->buf[0] = 0x67452301;

      ctx->buf[1] = 0xefcdab89;

      ctx->buf[2] = 0x98badcfe;

      ctx->buf[3] = 0x10325476;

 

      ctx->bytes[0] = 0;

      ctx->bytes[1] = 0;

}

 

/*

 * Update context to reflect the concatenation of another buffer full

 * of bytes.

 */

static void

MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)

{

      UWORD32 t;

 

      /* Update byte count */

 

      t = ctx->bytes[0];

      if ((ctx->bytes[0] = t + len) < t)

             ctx->bytes[1]++;  /* Carry from low to high */

 

      t = 64 - (t & 0x3f);      /* Space available in ctx->in (at least 1) */

      if (t > len) {

             memcpy((md5byte *)ctx->in + 64 - t, buf, len);

             return;

      }

      /* First chunk is an odd size */

      memcpy((md5byte *)ctx->in + 64 - t, buf, t);

      byteSwap(ctx->in, 16);

      MD5Transform(ctx->buf, ctx->in);

      buf += t;

      len -= t;

 

      /* Process data in 64-byte chunks */

      while (len >= 64) {

             memcpy(ctx->in, buf, 64);

             byteSwap(ctx->in, 16);

             MD5Transform(ctx->buf, ctx->in);

             buf += 64;

             len -= 64;

      }

 

      /* Handle any remaining bytes of data. */

      memcpy(ctx->in, buf, len);

}

 

/*

 * Final wrapup - pad to 64-byte boundary with the bit pattern

 * 1 0* (64-bit count of bits processed, MSB-first)

 */

static void

MD5Final(struct MD5Context *ctx, md5byte digest[16])

{

      int count = ctx->bytes[0] & 0x3f;    /* Number of bytes in ctx->in */

      md5byte *p = (md5byte *)ctx->in + count;

 

      /* Set the first char of padding to 0x80.  There is always room. */

      *p++ = 0x80;

 

      /* Bytes of padding needed to make 56 bytes (-8..55) */

      count = 56 - 1 - count;

 

      if (count < 0) {     /* Padding forces an extra block */

             memset(p, 0, count + 8);

             byteSwap(ctx->in, 16);

             MD5Transform(ctx->buf, ctx->in);

             p = (md5byte *)ctx->in;

             count = 56;

      }

      memset(p, 0, count);

      byteSwap(ctx->in, 14);

 

      /* Append length in bits and transform */

      ctx->in[14] = ctx->bytes[0] << 3;

      ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;

      MD5Transform(ctx->buf, ctx->in);

 

      byteSwap(ctx->buf, 4);

      memcpy(digest, ctx->buf, 16);

      memset(ctx, 0, sizeof(ctx));     /* In case it's sensitive */

}

 

#ifndef ASM_MD5

 

/* The four core functions - F1 is optimized somewhat */

 

/* #define F1(x, y, z) (x & y | ~x & z) */

#define F1(x, y, z) (z ^ (x & (y ^ z)))

#define F2(x, y, z) F1(z, x, y)

#define F3(x, y, z) (x ^ y ^ z)

#define F4(x, y, z) (y ^ (x | ~z))

 

/* This is the central step in the MD5 algorithm. */

#define MD5STEP(f,w,x,y,z,in,s) /

       (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)

 

/*

 * The core of the MD5 algorithm, this alters an existing MD5 hash to

 * reflect the addition of 16 longwords of new data.  MD5Update blocks

 * the data and converts bytes into longwords for this routine.

 */

static void

MD5Transform(UWORD32 buf[4], UWORD32 const in[16])

{

      register UWORD32 a, b, c, d;

 

      a = buf[0];

      b = buf[1];

      c = buf[2];

      d = buf[3];

 

      MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);

      MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);

      MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);

      MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);

      MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);

      MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);

      MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);

      MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);

      MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);

      MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);

      MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);

      MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);

      MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);

      MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);

      MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);

      MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);

 

      MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);

      MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);

      MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);

      MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);

      MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);

      MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);

      MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);

      MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);

      MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);

      MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);

      MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);

      MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);

      MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);

      MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);

      MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);

      MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);

 

      MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);

      MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);

      MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);

      MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);

      MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);

抱歉!评论已关闭.