md5 c语言加密程序,MD5 加密源码(C语言)

#include

#include

#include

#include

#define N 1024

#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 ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))

#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); }

#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); }

#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); }

#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); }

typedef unsigned char UINT8;

typedef unsigned int UINT32;

UINT32 s[64] = {

7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,

5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,

4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,

6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21},

t[64] = {

0Xd76aa478, 0Xe8c7b756, 0X242070db, 0Xc1bdceee,

0Xf57c0faf, 0X4787c62a, 0Xa8304613, 0Xfd469501,

0X698098d8, 0X8b44f7af, 0Xffff5bb1, 0X895cd7be,

0X6b901122, 0Xfd987193, 0Xa679438e, 0X49b40821,

0Xf61e2562, 0Xc040b340, 0X265e5a51, 0Xe9b6c7aa,

0Xd62f105d, 0X2441453, 0Xd8a1e681, 0Xe7d3fbc8,

0X21e1cde6, 0Xc33707d6, 0Xf4d50d87, 0X455a14ed,

0Xa9e3e905, 0Xfcefa3f8, 0X676f02d9, 0X8d2a4c8a,

0Xfffa3942, 0X8771f681, 0X6d9d6122, 0Xfde5380c,

0Xa4beea44, 0X4bdecfa9, 0Xf6bb4b60, 0Xbebfbc70,

0X289b7ec6, 0Xeaa127fa, 0Xd4ef3085, 0x4881d05,

0Xd9d4d039, 0Xe6db99e5, 0X1fa27cf8, 0Xc4ac5665,

0Xf4292244, 0X432aff97, 0Xab9423a7, 0Xfc93a039,

0X655b59c3, 0X8f0ccc92, 0Xffeff47d, 0X85845dd1,

0X6fa87e4f, 0Xfe2ce6e0, 0Xa3014314, 0X4e0811a1,

0Xf7537e82, 0Xbd3af235, 0X2ad7d2bb, 0Xeb86d391},

Index[64] = {

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,

1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,

5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,

0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9},

INIT[4] = {

0x67452301,

0xefcdab89,

0x98badcfe,

0x10325476};

//

// 工具函数 //

//

FILE *open(UINT8 *filename, UINT8 *mode) //打开文件

{

FILE *fp = NULL;

if((fp = fopen(filename, mode)) == NULL)

{

printf("file open error!\n");

exit(-1);

}

return fp;

}

void close(FILE *fp) //关闭文件

{

while(fclose(fp));

}

/*将整型数据转换成字符串数据*/

void encode(UINT32 *input, UINT8 *output, UINT32 len)

{

UINT32 i, j;

for(i = 0, j = 0; i < len; i += 4, j++)

{

output[i] = (UINT8)(input[j] & 0Xff);

output[i + 1] = (UINT8)((input[j] >> 8 ) & 0Xff);

output[i + 2] = (UINT8)((input[j] >> 16) & 0Xff);

output[i + 3] = (UINT8)((input[j] >> 24) & 0Xff);

}

}

/*将字符串转换成整型数据*/

void decode(UINT8 * input, UINT32 * output, UINT32 len)

{

UINT32 i = 0,

j = 0;

for(; i < len; i += 4, j++)

output[j] = (UINT32)input[i] | (((UINT32)input[i + 1])<<8) |

(((UINT32)input[i + 2])<<16) | (((UINT32)input[i + 3])<<24);

}

//

// 功能函数 //

//

/*初始化链块变量*/

void init_md5()

{

INIT[0] = 0x67452301;

INIT[1] = 0xefcdab89;

INIT[2] = 0x98badcfe;

INIT[3] = 0x10325476;

}

/*数字签名计算*/

void digest_opt(UINT8 *m, UINT32 len)

{

UINT32 i = 0, j = 0, k = 0, temp[4], date[16];

for(i = 0; i < 4; i++)

temp[i] = INIT[i];

/*对多个数据快进行签名运算*/

for(; len > 0; len -= 64, j += 4)

{

/*将64字节的字符串转换成16个整型数据*/

decode(m+j, date, 64);

for(i = 0; i < 64; i++, k = (k+4-1)%4)

{

switch(i/16)

{

case 0: FF(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[(k+3)%4], date[Index[i]], s[i], t[i]); break;

case 1: GG(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[(k+3)%4], date[Index[i]], s[i], t[i]); break;

case 2: HH(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[(k+3)%4], date[Index[i]], s[i], t[i]); break;

case 3: II(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[(k+3)%4], date[Index[i]], s[i], t[i]); break;

default: break;

}

}

}

for(i = 0; i < 4; i++)

INIT[i] += temp[i];

}

/*计算需要填充的字节长度*/

UINT32 pad_len(UINT32 len)

{

UINT32 mod;

mod = len%64;

/*p_len 为填充字节数计算*/

if(mod <= 56)

len = 64 - mod;

else

len = 128 - mod;

return len;

}

/*计算原消息长度的填充信息*/

void len_data(UINT8 * msgLen, const UINT32 len)

{

UINT32 bufLen[2];

/*计算数据长度的填充数据*/

bufLen[0] = len << 3;

bufLen[1] = len >> 29;

encode(bufLen, msgLen, 8);

}

/*字节填充*/

UINT8 * tail_pad(UINT8 * msg, UINT8 *msgLen, const UINT32 len, const UINT32 padLen)

{

UINT8 *buf = NULL;

/*根据填充字节数构建新串*/

buf = (UINT8 *)calloc(sizeof(UINT8), len + padLen);

/*初始化新串的值*/

memcpy(buf, msg, len);

buf[len] = 0X80;//若buf[len]为带符号字符型, 赋值后将变成负数

memcpy(buf + len + padLen - 8, msgLen, 8);

return buf;

}

/*对需要填充的消息进行数字签名*/

void md5_tail(UINT8 *msg, UINT8 *digest,const UINT32 len, UINT8 *msgLen)

{

UINT32 padLen, i;

UINT8 *buf = NULL;

padLen = pad_len(len);

buf = tail_pad(msg, msgLen, len, padLen);//填充字符串, 得到新串buf

digest_opt(buf, len + padLen); //数字签名计算

encode(INIT, digest, 16); //存储最终结果

free(buf);

}

/*对消息进行数字签名*/

void md5_msg(UINT8 *msg, UINT8 *digest)

{

UINT32 len = strlen(msg); //len为当前消息长度

UINT8 msgLen[8];

init_md5();

len_data(msgLen, len); //计算填充的长度信息

md5_tail(msg, digest, len, msgLen); //摘要计算

}

/*对文件进行数字签名*/

void md5_file(FILE *fp, UINT8 *digest)

{

UINT32 bufLen = 0,

fileLen = 0;

UINT8 buf[N], msgLen[8];

init_md5();

bufLen = fread(buf, sizeof(UINT8), N, fp);

fileLen += bufLen;

while(!feof(fp))

{

digest_opt(buf, N);

bufLen = fread(buf, sizeof(UINT8), N, fp);

fileLen += bufLen;

}

len_data(msgLen, fileLen - 1); //计算填充的长度信息

md5_tail(buf, digest, bufLen - 1, msgLen); //摘要计算

}

/*主测试函数*/

int main()

{

FILE * fp;

UINT8 digest[16];

UINT32 i;

fp = open("m", "r");

md5_file(fp, digest);

close(fp);

printf("file\tdigest: ");

for(i = 0; i < 16; i++)

printf("%02x", digest[i]);

printf("\n");

md5_msg("abc", digest);

printf("message\tdigest: ");

for(i = 0; i < 16; i++)

printf("%02x", digest[i]);

printf("\n");

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值