最近在看了看md5, 网上找了找资料学习一下。自己用c语言实现一次,加深映象。
涉及知识:
1.位操作
2.md5的算法
md5.h文件
namespace MD5
{
#define F(x,y,z) (((x) & (y)) | ((~x) & (z)))
#define G(x,y,z) (((x) & (z)) | ((y) & (~z)))
#define H(x,y,z) ((x) ^ (y) ^ (z))
#define I(x,y,z) ((y) ^ ((x) | (~z)))
#define ROTAE(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
#define FF(a,b,c,d,mj,s,ti)\
{\
a += F(b,c,d) + mj + ti; \
a = ROTAE(a,s); \
a += b; \
}
#define GG(a,b,c,d,mj,s,ti)\
{\
a += G(b,c,d) + mj + ti; \
a = ROTAE(a,s); \
a += b; \
}
#define HH(a,b,c,d,mj,s,ti)\
{\
a += H(b,c,d) + mj + ti; \
a = ROTAE(a,s); \
a += b; \
}
#define II(a,b,c,d,mj,s,ti)\
{\
a += I(b,c,d) + mj + ti; \
a = ROTAE(a,s); \
a += b; \
}
char* add(const char *source, long &length);
char* getMD5(char *source);
void changeIndex(char *data, int a);
}
md5.cpp
#include "MD5.hpp"
#include <cstring>
#include <stdlib.h>
#include <string>
namespace MD5 {
void calueMD5(unsigned int abcd[4], unsigned int block[64]);
#define TEMPA 0x67452301
#define TEMPB 0xEFCDAB89
#define TEMPC 0x98badcfe
#define TEMPD 0x10325476
//获取md5 字符串
char* getMD5(char *source)
{
//长度
long length = 0;
//填充字符串
char *result = add(source, length);
//初始化
unsigned int temp[4] = {TEMPA, TEMPB, TEMPC, TEMPD};
//计算md5
for (int i = 0; i < length ; i++) {
calueMD5(temp, (unsigned int*)result);
}
//顺序输出
char *mdstring = (char *) malloc(256);
for (int i = 0; i < 4; i++) {
changeIndex(mdstring + i * 8, temp[i]);
}
delete result;
return mdstring;
}
//数据填充
/**
*
*
* @param source 输入
* @param result 输出
* @param length 字节数,为64倍数
*/
char* add(const char *source, long &length)
{
//长度 N * 64字节
length = (strlen(source) + 8) / 64 + 1;
char * result = (char*)malloc(sizeof(char) * length * 64);
size_t i = 0;
for (; i < strlen(source) + 1; i++) {
(result)[i] = source[i];
}
(result)[--i] = 1 << 7;
i++;
for (; i < length * 64 - 8; i++) {
(result)[i] = 0;
}
long * p = (long *)result;
p[length * 8 - 1] = strlen(source) * 8;
return result;
}
//逆序
void changeIndex(char *data, int a)
{
char *p = data;
sprintf(p, "%02x%02x%02x%02x", (a & 0x000000ff), (a & 0x0000ff00) >> 8, (a & 0x00ff0000) >> 16, (a & 0xff000000) >> 24);
}
//计算
void calueMD5(unsigned int abcd[4], unsigned int x[16])
{
unsigned int a = abcd[0];
unsigned int b = abcd[1];
unsigned int c = abcd[2];
unsigned int d = abcd[3];
FF(a ,b ,c ,d ,x[0] ,7 ,0xd76aa478 );
FF(d ,a ,b ,c ,x[1] ,12 ,0xe8c7b756 );
FF(c ,d ,a ,b ,x[2] ,17 ,0x242070db );
FF(b ,c ,d ,a ,x[3] ,22 ,0xc1bdceee );
FF(a ,b ,c ,d ,x[4] ,7 ,0xf57c0faf );
FF(d ,a ,b ,c ,x[5] ,12 ,0x4787c62a );
FF(c ,d ,a ,b ,x[6] ,17 ,0xa8304613 );
FF(b ,c ,d ,a ,x[7] ,22 ,0xfd469501);
FF(a ,b ,c ,d ,x[8] ,7 ,0x698098d8 );
FF(d ,a ,b ,c ,x[9] ,12 ,0x8b44f7af );
FF(c ,d ,a ,b ,x[10] ,17 ,0xffff5bb1 );
FF(b ,c ,d ,a ,x[11] ,22 ,0x895cd7be );
FF(a ,b ,c ,d ,x[12] ,7 ,0x6b901122 );
FF(d ,a ,b ,c ,x[13] ,12 ,0xfd987193 );
FF(c ,d ,a ,b ,x[14] ,17 ,0xa679438e );
FF(b ,c ,d ,a ,x[15] ,22 ,0x49b40821 );
GG(a ,b ,c ,d ,x[1] ,5 ,0xf61e2562 )
GG(d ,a ,b ,c ,x[6] ,9 ,0xc040b340 )
GG(c ,d ,a ,b ,x[11] ,14 ,0x265e5a51 )
GG(b ,c ,d ,a ,x[0] ,20 ,0xe9b6c7aa )
GG(a ,b ,c ,d ,x[5] ,5 ,0xd62f105d )
GG(d ,a ,b ,c ,x[10] ,9 ,0x02441453 )
GG(c ,d ,a ,b ,x[15] ,14 ,0xd8a1e681 )
GG(b ,c ,d ,a ,x[4] ,20 ,0xe7d3fbc8 )
GG(a ,b ,c ,d ,x[9] ,5 ,0x21e1cde6 )
GG(d ,a ,b ,c ,x[14] ,9 ,0xc33707d6 )
GG(c ,d ,a ,b ,x[3] ,14 ,0xf4d50d87 )
GG(b ,c ,d ,a ,x[8] ,20 ,0x455a14ed )
GG(a ,b ,c ,d ,x[13] ,5 ,0xa9e3e905 )
GG(d ,a ,b ,c ,x[2] ,9 ,0xfcefa3f8 )
GG(c ,d ,a ,b ,x[7] ,14 ,0x676f02d9 )
GG(b ,c ,d ,a ,x[12] ,20 ,0x8d2a4c8a )
HH(a ,b ,c ,d ,x[5] ,4 ,0xfffa3942 )
HH(d ,a ,b ,c ,x[8] ,11 ,0x8771f681 )
HH(c ,d ,a ,b ,x[11] ,16 ,0x6d9d6122 )
HH(b ,c ,d ,a ,x[14],23 ,0xfde5380c )
HH(a ,b ,c ,d ,x[1] ,4 ,0xa4beea44 )
HH(d ,a ,b ,c ,x[4] ,11 ,0x4bdecfa9 )
HH(c ,d ,a ,b ,x[7] ,16 ,0xf6bb4b60 )
HH(b ,c ,d ,a ,x[10] ,23 ,0xbebfbc70 )
HH(a ,b ,c ,d ,x[13],4 ,0x289b7ec6 )
HH(d ,a ,b ,c ,x[0] ,11 ,0xeaa127fa )
HH(c ,d ,a ,b ,x[3] ,16 ,0xd4ef3085 )
HH(b ,c ,d ,a ,x[6] ,23 ,0x04881d05 )
HH(a ,b ,c ,d ,x[9] ,4 ,0xd9d4d039 )
HH(d ,a ,b ,c ,x[12] ,11 ,0xe6db99e5 )
HH(c ,d ,a ,b ,x[15],16 ,0x1fa27cf8 )
HH(b ,c ,d ,a ,x[2] ,23 ,0xc4ac5665 )
II(a ,b ,c ,d ,x[0] ,6 ,0xf4292244 )
II(d ,a ,b ,c ,x[7] ,10 ,0x432aff97 )
II(c ,d ,a ,b ,x[14] ,15 ,0xab9423a7 )
II(b ,c ,d ,a ,x[5] ,21 ,0xfc93a039 )
II(a ,b ,c ,d ,x[12] ,6 ,0x655b59c3 )
II(d ,a ,b ,c ,x[3] ,10 ,0x8f0ccc92 )
II(c ,d ,a ,b ,x[10] ,15 ,0xffeff47d )
II(b ,c ,d ,a ,x[1] ,21 ,0x85845dd1 )
II(a ,b ,c ,d ,x[8] ,6 ,0x6fa87e4f )
II(d ,a ,b ,c ,x[15] ,10 ,0xfe2ce6e0 )
II(c ,d ,a ,b ,x[6] ,15 ,0xa3014314 )
II(b ,c ,d ,a ,x[13] ,21 ,0x4e0811a1 )
II(a ,b ,c ,d ,x[4] ,6 ,0xf7537e82 )
II(d ,a ,b ,c ,x[11] ,10 ,0xbd3af235 )
II(c ,d ,a ,b ,x[2] ,15 ,0x2ad7d2bb )
II(b ,c ,d ,a ,x[9] ,21 ,0xeb86d391 )
abcd[0] += a;
abcd[1] += b;
abcd[2] += c;
abcd[3] += d;
}
}