bman's it blog

Do our coding

自己实现了遍MD5信息摘要算法

主要代码:
typedef unsigned char    byte;
typedef 
int              int32;
typedef unsigned         uint32;
typedef __int64          int64;
typedef unsigned __int64 uint64;

typedef 
struct _int128 {
    int32 A;
    int32 B;
    int32 C;
    int32 D;
}
 int128;

typedef 
struct _uint128 {
    uint32 A;
    uint32 B;
    uint32 C;
    uint32 D;
}
 uint128;

#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21

// word A: 01 23 45 67
#define WORD_A 0x67452301
// word B: 89 ab cd ef
#define WORD_B 0xefcdab89
// word C: fe dc ba 98
#define WORD_C 0x98badcfe
// word D: 76 54 32 10
#define WORD_D 0x10325476

// F(X,Y,Z) = XY v not(X) Z    == (X and Y) or (not(X) and Z)
#define F(X,Y,Z) (((X) & (Y)) | ((~(X)) & (Z)))
// G(X,Y,Z) = XZ v Y not(Z)    == (X and Z) or (Y and not(Z))
#define G(X,Y,Z) (((X) & (Z)) | ((Y) & (~(Z))))
// H(X,Y,Z) = X xor Y xor Z    == X xor Y xor Z
#define H(X,Y,Z) ((X) ^ (Y) ^ (Z))
// I(X,Y,Z) = Y xor (X v not(Z))    == Y xor (X or not(Z))
#define I(X,Y,Z) ((Y) ^ ((X) | (~(Z))))

// 左移n位
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
// a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
#define FF(a, b, c, d, x, s, ac) { \
    (a) 
+= F ((b), (c), (d)) + (x) + (uint32)(ac); \
    (a) 
= ROTATE_LEFT ((a), (s)); \
    (a) 
+= (b); \
}
// a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
#define GG(a, b, c, d, x, s, ac) { \
    (a) 
+= G ((b), (c), (d)) + (x) + (uint32)(ac); \
    (a) 
= ROTATE_LEFT ((a), (s)); \
    (a) 
+= (b); \
}
// a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
#define HH(a, b, c, d, x, s, ac) { \
    (a) 
+= H ((b), (c), (d)) + (x) + (uint32)(ac); \
    (a) 
= ROTATE_LEFT ((a), (s)); \
    (a) 
+= (b); \
}
// a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
#define II(a, b, c, d, x, s, ac) { \
    (a) 
+= I ((b), (c), (d)) + (x) + (uint32)(ac); \
    (a) 
= ROTATE_LEFT ((a), (s)); \
    (a) 
+= (b); \
}

// len要是4的倍数
void MD5Encode (byte* output, uint32* input, unsigned int len)
{
    unsigned 
int i, j;
    
for (i = 0, j = 0; j < len; i++, j += 4{
        output[j] 
= (byte)(input[i] & 0xff);
        output[j
+1= (byte)((input[i] >> 8& 0xff);
        output[j
+2= (byte)((input[i] >> 16& 0xff);
        output[j
+3= (byte)((input[i] >> 24& 0xff);
    }

}


// len要是4的倍数
void MD5Decode (uint32* output, byte* input, unsigned int len)
{
    unsigned 
int i, j;
    
for (i = 0, j = 0; j < len; i++, j += 4)
        output[i] 
= ((uint32)input[j]) | (((uint32)input[j+1]) << 8|
            (((uint32)input[j
+2]) << 16| (((uint32)input[j+3]) << 24);
}


void MD5Memcpy (byte* output, byte* input, unsigned int len)
{
    unsigned 
int i;
    
for (i = 0; i < len; i++)
        output[i] 
= input[i];
}


void MD5Memset (byte* output, int value, unsigned int len)
{
    unsigned 
int i;
    
for (i = 0; i < len; i++)
        ((
byte*)output)[i] = (byte)value;
}


void MD5Transform (uint128* statePtr, byte block[64]) {
    uint32 a 
= statePtr->A, b = statePtr->B,
        c 
= statePtr->C, d = statePtr->D, x[16];

    MD5Decode(x, block, 
64);

    
/* Round 1 */
    FF (a, b, c, d, x[ 
0], S11, 0xd76aa478); /* 1 */
    FF (d, a, b, c, x[ 
1], S12, 0xe8c7b756); /* 2 */
    FF (c, d, a, b, x[ 
2], S13, 0x242070db); /* 3 */
    FF (b, c, d, a, x[ 
3], S14, 0xc1bdceee); /* 4 */
    FF (a, b, c, d, x[ 
4], S11, 0xf57c0faf); /* 5 */
    FF (d, a, b, c, x[ 
5], S12, 0x4787c62a); /* 6 */
    FF (c, d, a, b, x[ 
6], S13, 0xa8304613); /* 7 */
    FF (b, c, d, a, x[ 
7], S14, 0xfd469501); /* 8 */
    FF (a, b, c, d, x[ 
8], S11, 0x698098d8); /* 9 */
    FF (d, a, b, c, x[ 
9], S12, 0x8b44f7af); /* 10 */
    FF (c, d, a, b, x[
10], S13, 0xffff5bb1); /* 11 */
    FF (b, c, d, a, x[
11], S14, 0x895cd7be); /* 12 */
    FF (a, b, c, d, x[
12], S11, 0x6b901122); /* 13 */
    FF (d, a, b, c, x[
13], S12, 0xfd987193); /* 14 */
    FF (c, d, a, b, x[
14], S13, 0xa679438e); /* 15 */
    FF (b, c, d, a, x[
15], S14, 0x49b40821); /* 16 */

    
/* Round 2 */
    GG (a, b, c, d, x[ 
1], S21, 0xf61e2562); /* 17 */
    GG (d, a, b, c, x[ 
6], S22, 0xc040b340); /* 18 */
    GG (c, d, a, b, x[
11], S23, 0x265e5a51); /* 19 */
    GG (b, c, d, a, x[ 
0], S24, 0xe9b6c7aa); /* 20 */
    GG (a, b, c, d, x[ 
5], S21, 0xd62f105d); /* 21 */
    GG (d, a, b, c, x[
10], S22,  0x2441453); /* 22 */
    GG (c, d, a, b, x[
15], S23, 0xd8a1e681); /* 23 */
    GG (b, c, d, a, x[ 
4], S24, 0xe7d3fbc8); /* 24 */
    GG (a, b, c, d, x[ 
9], S21, 0x21e1cde6); /* 25 */
    GG (d, a, b, c, x[
14], S22, 0xc33707d6); /* 26 */
    GG (c, d, a, b, x[ 
3], S23, 0xf4d50d87); /* 27 */
    GG (b, c, d, a, x[ 
8], S24, 0x455a14ed); /* 28 */
    GG (a, b, c, d, x[
13], S21, 0xa9e3e905); /* 29 */
    GG (d, a, b, c, x[ 
2], S22, 0xfcefa3f8); /* 30 */
    GG (c, d, a, b, x[ 
7], S23, 0x676f02d9); /* 31 */
    GG (b, c, d, a, x[
12], S24, 0x8d2a4c8a); /* 32 */

    
/* Round 3 */
    HH (a, b, c, d, x[ 
5], S31, 0xfffa3942); /* 33 */
    HH (d, a, b, c, x[ 
8], S32, 0x8771f681); /* 34 */
    HH (c, d, a, b, x[
11], S33, 0x6d9d6122); /* 35 */
    HH (b, c, d, a, x[
14], S34, 0xfde5380c); /* 36 */
    HH (a, b, c, d, x[ 
1], S31, 0xa4beea44); /* 37 */
    HH (d, a, b, c, x[ 
4], S32, 0x4bdecfa9); /* 38 */
    HH (c, d, a, b, x[ 
7], S33, 0xf6bb4b60); /* 39 */
    HH (b, c, d, a, x[
10], S34, 0xbebfbc70); /* 40 */
    HH (a, b, c, d, x[
13], S31, 0x289b7ec6); /* 41 */
    HH (d, a, b, c, x[ 
0], S32, 0xeaa127fa); /* 42 */
    HH (c, d, a, b, x[ 
3], S33, 0xd4ef3085); /* 43 */
    HH (b, c, d, a, x[ 
6], S34,  0x4881d05); /* 44 */
    HH (a, b, c, d, x[ 
9], S31, 0xd9d4d039); /* 45 */
    HH (d, a, b, c, x[
12], S32, 0xe6db99e5); /* 46 */
    HH (c, d, a, b, x[
15], S33, 0x1fa27cf8); /* 47 */
    HH (b, c, d, a, x[ 
2], S34, 0xc4ac5665); /* 48 */

    
/* Round 4 */
    II (a, b, c, d, x[ 
0], S41, 0xf4292244); /* 49 */
    II (d, a, b, c, x[ 
7], S42, 0x432aff97); /* 50 */
    II (c, d, a, b, x[
14], S43, 0xab9423a7); /* 51 */
    II (b, c, d, a, x[ 
5], S44, 0xfc93a039); /* 52 */
    II (a, b, c, d, x[
12], S41, 0x655b59c3); /* 53 */
    II (d, a, b, c, x[ 
3], S42, 0x8f0ccc92); /* 54 */
    II (c, d, a, b, x[
10], S43, 0xffeff47d); /* 55 */
    II (b, c, d, a, x[ 
1], S44, 0x85845dd1); /* 56 */
    II (a, b, c, d, x[ 
8], S41, 0x6fa87e4f); /* 57 */
    II (d, a, b, c, x[
15], S42, 0xfe2ce6e0); /* 58 */
    II (c, d, a, b, x[ 
6], S43, 0xa3014314); /* 59 */
    II (b, c, d, a, x[
13], S44, 0x4e0811a1); /* 60 */
    II (a, b, c, d, x[ 
4], S41, 0xf7537e82); /* 61 */
    II (d, a, b, c, x[
11], S42, 0xbd3af235); /* 62 */
    II (c, d, a, b, x[ 
2], S43, 0x2ad7d2bb); /* 63 */
    II (b, c, d, a, x[ 
9], S44, 0xeb86d391); /* 64 */

    statePtr
->+= a;
    statePtr
->+= b;
    statePtr
->+= c;
    statePtr
->+= d;
}


// ptr为数据指针,len为数据长度(以位为单位)
byte* MD5Append (byte* ptr, uint64 len, unsigned int* num) {
    
/* 计算需补字节数 */
    unsigned 
int ll = len >> 3// 从位数计算字节数
    unsigned int m = 64 - (ll % 64); // 需要填充多少字节
    if (m <= 8) m += 64// 如果不够放置原始数据长度就增加64字节
    unsigned int m10 = m - 8// 需要填充几字节10,留64位给原始数据长度

    
// 分配内存用来放置
    unsigned int n = ll - (ll % 64); // 刚好为64的倍数的数据长度
    byte* bufPtr = (byte*)malloc(ll - n + m);
    
*num = ll - n + m;

    
// 把多余数据复制到缓冲里
    MD5Memcpy(bufPtr, &ptr[n], ll - n);

    
/* 补'1'0字节 */
    unsigned 
int index = ll - n; // 补位偏移位置
    bufPtr[index] = (byte)0x80// '1'
    for (int i = 1; i < m10; i++{
        bufPtr[index 
+ i] = 0;
    }


    
/* 添加原始数据长度 */
    
byte bits[8];
    MD5Encode(bits, (uint32
*)&len, 8);
    
int j = ll - n + m - 8// 添加数据起始位置
    for (int i = 0; i < 8; i++{
        bufPtr[j
++= bits[i];
    }


    
return bufPtr;
}


// ptr为数据指针,len为数据长度(以位为单位)
uint128 MD5 (byte* ptr, uint64 len) {
    
// 初始化4个变量
    uint32 A = WORD_A;
    uint32 B 
= WORD_B;
    uint32 C 
= WORD_C;
    uint32 D 
= WORD_D;
    uint128 state 
= {A, B, C, D};

    
// 对数据进行计算
    unsigned int m = len >> 3// 位到字节
    unsigned int n = m / 64;
    
for (int i = 0, p = 0; i < n; i++, p += 64{
        MD5Transform(
&state, &ptr[p]);
    }


    
// 补位,添加原始数据长度
    unsigned int num = 0// 缓冲长度
    byte* appendBuf = MD5Append (ptr, len, &num);

    
// 对补充后的缓冲进行计算
    n = num / 64;
    
for (int i = 0, p = 0; i < n; i++, p += 64{
        MD5Transform(
&state, &appendBuf[p]);
    }


    free(appendBuf);
    
return state;
}


void print_uint128 (uint128 value) {
    unsigned 
char digest[16];
    MD5Encode (digest, (uint32
*)&value, 16);
    
for (int i = 0; i < 16; i++)
        printf (
"%02x", digest[i]);
}

实现环境VS2005 代码下载:
/Files/bman/MyMD5.rar

posted on 2008-02-23 21:10 bman 阅读(504) 评论(2)  编辑 收藏 引用 所属分类: 笔记

评论

# re: 自己实现了遍MD5信息摘要算法 2008-02-23 21:36 小酒

很好很强大  回复  更多评论   

# re: 自己实现了遍MD5信息摘要算法 2008-05-06 22:09 acc

真是你自己实现的吗? 好猛啊~  回复  更多评论   

只有注册用户登录后才能发表评论。

导航

<2008年3月>
2425262728291
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

常用链接

留言簿(2)

随笔分类

随笔档案

最新随笔

搜索

积分与排名

最新随笔

最新评论

阅读排行榜

评论排行榜