# fluyy/fluyy_code

Switch branches/tags
Nothing to show
Fetching contributors…
Cannot retrieve contributors at this time
288 lines (235 sloc) 7.63 KB
 /* * ===================================================================================== * * Filename: md5.c * * Description: md5消息摘要算法的实现 * * Version: 1.0 * Created: 04/04/2014 04:15:42 FFM * Revision: none * Compiler: gcc * * Author: Fluyy (), tulneer@gmail.com * Blog: http://blog.fluyy.net * Organization: * * ===================================================================================== */ #include "md5_core.h" #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 S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) #define FF(a,b,c,d,k,s,t) \ { \ a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ } #define GG(a,b,c,d,k,s,t) \ { \ a += G(b,c,d) + X[k] + t; a = S(a,s) + b; \ } #define HH(a,b,c,d,k,s,t) \ { \ a += H(b,c,d) + X[k] + t; a = S(a,s) + b; \ } #define II(a,b,c,d,k,s,t) \ { \ a += I(b,c,d) + X[k] + t; a = S(a,s) + b; \ } unsigned char padding[64]; /*==================================== * * md5初始化部分 * 初始化4个state初始值 * *=====================================*/ int md5_init(CONTEXT *context){ context->state[0]=0x67452301; context->state[1]=0xefcdab89; context->state[2]=0x98badcfe; context->state[3]=0x10325476; context->count[0]=context->count[1]=0; memset(padding,0,sizeof(padding)); padding[0]=0x80; return 0; } /*==================================== * * 对数据进行填充和分割成64个字节一组 * 然后循环对每组数据进行md5_process操作 * *=====================================*/ int md5_update(CONTEXT *context,unsigned char *input,unsigned int inputlen){ /*left 表示缓冲区中剩余未处理的数据长度，单位byte*/ UINT4 left; /*partlen 需要填充的数据长度，单位为byte*/ unsigned int partlen; left=(UINT4)((context->count[0]>>3)&0x3f); context->count[0]+=(UINT4)(inputlen<<3); /*低位产生一个进位到高位*/ if(context->count[0]<(UINT4)(inputlen<<3)) context->count[1]++; context->count[1] += ((UINT4)inputlen >> 29); partlen=64-left; /*新数据长度比需要填充的长度长时，可以组成一个新的128bit数据，可以进行一次md5 process*/ if(left && inputlen>=partlen){ memcpy((void*)(context->buffer+left),input,partlen); md5_process(context,context->buffer); input+=partlen; inputlen-=partlen; left=0; } /*循环处理缓存区内容*/ while(inputlen>=64){ md5_process(context,input); input+=64; inputlen-=64; } /*还有部分数据时，留到下次处理，保存下来，下次处理*/ if(inputlen>0){ memcpy((void *)(context->buffer+left),input,inputlen); } return 0; } /* *=========================================== * * md5_process操作主要是： * 对数据进行4轮变换 * *=========================================== */ int md5_process(CONTEXT *context,unsigned char *data){ UINT4 A=context->state[0]; UINT4 B=context->state[1]; UINT4 C=context->state[2]; UINT4 D=context->state[3]; UINT4 X[16]; md5_decode(X,data,64); //round1 FF( A, B, C, D, 0, 7, 0xD76AA478 ); FF( D, A, B, C, 1, 12, 0xE8C7B756 ); FF( C, D, A, B, 2, 17, 0x242070DB ); FF( B, C, D, A, 3, 22, 0xC1BDCEEE ); FF( A, B, C, D, 4, 7, 0xF57C0FAF ); FF( D, A, B, C, 5, 12, 0x4787C62A ); FF( C, D, A, B, 6, 17, 0xA8304613 ); FF( B, C, D, A, 7, 22, 0xFD469501 ); FF( A, B, C, D, 8, 7, 0x698098D8 ); FF( D, A, B, C, 9, 12, 0x8B44F7AF ); FF( C, D, A, B, 10, 17, 0xFFFF5BB1 ); FF( B, C, D, A, 11, 22, 0x895CD7BE ); FF( A, B, C, D, 12, 7, 0x6B901122 ); FF( D, A, B, C, 13, 12, 0xFD987193 ); FF( C, D, A, B, 14, 17, 0xA679438E ); FF( B, C, D, A, 15, 22, 0x49B40821 ); //round2 GG( A, B, C, D, 1, 5, 0xF61E2562 ); GG( D, A, B, C, 6, 9, 0xC040B340 ); GG( C, D, A, B, 11, 14, 0x265E5A51 ); GG( B, C, D, A, 0, 20, 0xE9B6C7AA ); GG( A, B, C, D, 5, 5, 0xD62F105D ); GG( D, A, B, C, 10, 9, 0x02441453 ); GG( C, D, A, B, 15, 14, 0xD8A1E681 ); GG( B, C, D, A, 4, 20, 0xE7D3FBC8 ); GG( A, B, C, D, 9, 5, 0x21E1CDE6 ); GG( D, A, B, C, 14, 9, 0xC33707D6 ); GG( C, D, A, B, 3, 14, 0xF4D50D87 ); GG( B, C, D, A, 8, 20, 0x455A14ED ); GG( A, B, C, D, 13, 5, 0xA9E3E905 ); GG( D, A, B, C, 2, 9, 0xFCEFA3F8 ); GG( C, D, A, B, 7, 14, 0x676F02D9 ); GG( B, C, D, A, 12, 20, 0x8D2A4C8A ); //round3 HH( A, B, C, D, 5, 4, 0xFFFA3942 ); HH( D, A, B, C, 8, 11, 0x8771F681 ); HH( C, D, A, B, 11, 16, 0x6D9D6122 ); HH( B, C, D, A, 14, 23, 0xFDE5380C ); HH( A, B, C, D, 1, 4, 0xA4BEEA44 ); HH( D, A, B, C, 4, 11, 0x4BDECFA9 ); HH( C, D, A, B, 7, 16, 0xF6BB4B60 ); HH( B, C, D, A, 10, 23, 0xBEBFBC70 ); HH( A, B, C, D, 13, 4, 0x289B7EC6 ); HH( D, A, B, C, 0, 11, 0xEAA127FA ); HH( C, D, A, B, 3, 16, 0xD4EF3085 ); HH( B, C, D, A, 6, 23, 0x04881D05 ); HH( A, B, C, D, 9, 4, 0xD9D4D039 ); HH( D, A, B, C, 12, 11, 0xE6DB99E5 ); HH( C, D, A, B, 15, 16, 0x1FA27CF8 ); HH( B, C, D, A, 2, 23, 0xC4AC5665 ); //round4 II( A, B, C, D, 0, 6, 0xF4292244 ); II( D, A, B, C, 7, 10, 0x432AFF97 ); II( C, D, A, B, 14, 15, 0xAB9423A7 ); II( B, C, D, A, 5, 21, 0xFC93A039 ); II( A, B, C, D, 12, 6, 0x655B59C3 ); II( D, A, B, C, 3, 10, 0x8F0CCC92 ); II( C, D, A, B, 10, 15, 0xFFEFF47D ); II( B, C, D, A, 1, 21, 0x85845DD1 ); II( A, B, C, D, 8, 6, 0x6FA87E4F ); II( D, A, B, C, 15, 10, 0xFE2CE6E0 ); II( C, D, A, B, 6, 15, 0xA3014314 ); II( B, C, D, A, 13, 21, 0x4E0811A1 ); II( A, B, C, D, 4, 6, 0xF7537E82 ); II( D, A, B, C, 11, 10, 0xBD3AF235 ); II( C, D, A, B, 2, 15, 0x2AD7D2BB ); II( B, C, D, A, 9, 21, 0xEB86D391 ); context->state[0]+=A; context->state[1]+=B; context->state[2]+=C; context->state[3]+=D; return 0; } /**/ int md5_final(CONTEXT *context,unsigned char *buf){ UINT4 left; UINT4 padlen; //数据要添加8个字节的数据长度 unsigned char msglen[8]; md5_encode(msglen,context->count,8); //求出需要填充字节长度 left=(UINT4)((context->count[0]>>3) & 0x3f); padlen=(left<56)?(56-left):(120-left); //添加填充位 md5_update(context,padding,padlen); //添加数据长度 md5_update(context,msglen,8); //将最终值编码到buffer中,即将128位的信息输出 md5_encode(buf,context->state,16); return 0; } /* *======================================================= * *将UINT4信息编码为unsigned char *将input里的数据转换为小端字节序存放在output中 * *======================================================= */ int md5_encode (unsigned char *output, UINT4 *input, unsigned int len) { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4){ output[j] = (unsigned char)(input[i] & 0xff); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); } return 0; } /*=================================================== * *将4个unsigned char 输出到unsigned int中 * *==================================================== */ int md5_decode (UINT4 *output, unsigned char *input, unsigned int len) { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); return 0; }