#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
//循环左移n位
int cir_left(int source,int n)
{
unsigned int tmp = source;
//int temp2=(source << n)|(source >> (32-n));
int adsddf = (tmp << n)|(tmp >> (32-n));
return (tmp << n)|(tmp >> (32-n));
}
//transfer char array[] to int array[]
void encode_c2i(char C_array[],int I_array[],int length) //I_array[](in)是16位数组,C_array[](tmp)是64位数组
{
int i,j;
for(i = 0; i < length; i++)
{
I_array[i] = (C_array[i*4]&0x000000ff) + ((C_array[i*4+1]<<8)&0x0000ff00)
+ ((C_array[i*4+2]<<16)&0x00ff0000) + ((C_array[i*4+3]<<24)&0xff000000);
I_array[i] = 0;
for(j = 3; j >= 0; j--)
{
I_array[i] = I_array[i] << 8;
I_array[i] += ((int)C_array[i*4+j])&0x000000ff;
}
}
}
//transfer int array[16] to char array[64]
void decode_i2c(int I_array[],char C_array[],int length)
{
int i;
for(i = 0; i < length; i++)
{
C_array[i*4] = I_array[i];
C_array[i*4+1] = I_array[i] >> 8;
C_array[i*4+2] = I_array[i] >> 16;
C_array[i*4+3] = I_array[i] >> 24;
}
}
int fun_F(int in, int y, int z)
{
return (in&y)|(~(in)&z);
}
int fun_G(int in, int y, int z)
{
return (in&z)|(y&~(z));
}
int fun_H(int in, int y, int z)
{
return in^y^z;
}
int fun_I(int in, int y, int z)
{
return y^(in|~(z));
}
int fun_FF(int a, int b,int c, int d, int Xk, int s, int Ti)
{
int tmp;
tmp = a + fun_F(b,c,d) + Xk + Ti;
return b + cir_left(tmp,s);
}
int fun_GG(int a, int b,int c, int d, int Xk, int s, int Ti)
{
int tmp;
tmp = a + fun_G(b,c,d) + Xk + Ti;
return b + cir_left(tmp,s);
}
int fun_HH(int a, int b,int c, int d, int Xk, int s, int Ti)
{
int tmp;
tmp = a + fun_H(b,c,d) + Xk + Ti;
return b + cir_left(tmp,s);
}
int fun_II(int a, int b,int c, int d, int Xk, int s, int Ti)
{
int tmp;
tmp = a + fun_I(b,c,d) + Xk + Ti;
return b + cir_left(tmp,s);
}
//实现64个字节的转换
void MD5_kerl(int in[16],int out[4],int T[64]) //作用变化out数组
{
int out_cpy[4];
int i;
for(i = 0; i < 4; i++)
{
out_cpy[i] = out[i];
}
//first loop
out[0] = fun_FF(out[0],out[1],out[2],out[3],in[0],7,T[0]);
out[3] = fun_FF(out[3],out[0],out[1],out[2],in[1],12,T[1]);
out[2] = fun_FF(out[2],out[3],out[0],out[1],in[2],17,T[2]);
out[1] = fun_FF(out[1],out[2],out[3],out[0],in[3],22,T[3]);
out[0] = fun_FF(out[0],out[1],out[2],out[3],in[4],7,T[4]);
out[3] = fun_FF(out[3],out[0],out[1],out[2],in[5],12,T[5]);
out[2] = fun_FF(out[2],out[3],out[0],out[1],in[6],17,T[6]);
out[1] = fun_FF(out[1],out[2],out[3],out[0],in[7],22,T[7]);
out[0] = fun_FF(out[0],out[1],out[2],out[3],in[8],7,T[8]);
out[3] = fun_FF(out[3],out[0],out[1],out[2],in[9],12,T[9]);
out[2] = fun_FF(out[2],out[3],out[0],out[1],in[10],17,T[10]);
out[1] = fun_FF(out[1],out[2],out[3],out[0],in[11],22,T[11]);
out[0] = fun_FF(out[0],out[1],out[2],out[3],in[12],7,T[12]);
out[3] = fun_FF(out[3],out[0],out[1],out[2],in[13],12,T[13]);
out[2] = fun_FF(out[2],out[3],out[0],out[1],in[14],17,T[14]);
out[1] = fun_FF(out[1],out[2],out[3],out[0],in[15],22,T[15]);
//second loop
out[0] = fun_GG(out[0],out[1],out[2],out[3],in[1],5,T[16]);
out[3] = fun_GG(out[3],out[0],out[1],out[2],in[6],9,T[17]);
out[2] = fun_GG(out[2],out[3],out[0],out[1],in[11],14,T[18]);
out[1] = fun_GG(out[1],out[2],out[3],out[0],in[0],20,T[19]);
out[0] = fun_GG(out[0],out[1],out[2],out[3],in[5],5,T[20]);
out[3] = fun_GG(out[3],out[0],out[1],out[2],in[10],9,T[21]);
out[2] = fun_GG(out[2],out[3],out[0],out[1],in[15],14,T[22]);
out[1] = fun_GG(out[1],out[2],out[3],out[0],in[4],20,T[23]);
out[0] = fun_GG(out[0],out[1],out[2],out[3],in[9],5,T[24]);
out[3] = fun_GG(out[3],out[0],out[1],out[2],in[14],9,T[25]);
out[2] = fun_GG(out[2],out[3],out[0],out[1],in[3],14,T[26]);
out[1] = fun_GG(out[1],out[2],out[3],out[0],in[8],20,T[27]);
out[0] = fun_GG(out[0],out[1],out[2],out[3],in[13],5,T[28]);
out[3] = fun_GG(out[3],out[0],out[1],out[2],in[2],9,T[29]);
out[2] = fun_GG(out[2],out[3],out[0],out[1],in[7],14,T[30]);
out[1] = fun_GG(out[1],out[2],out[3],out[0],in[12],20,T[31]);
//third loop
out[0] = fun_HH(out[0],out[1],out[2],out[3],in[5],4,T[32]);
out[3] = fun_HH(out[3],out[0],out[1],out[2],in[8],11,T[33]);
out[2] = fun_HH(out[2],out[3],out[0],out[1],in[11],16,T[34]);
out[1] = fun_HH(out[1],out[2],out[3],out[0],in[14],23,T[35]);
out[0] = fun_HH(out[0],out[1],out[2],out[3],in[1],4,T[36]);
out[3] = fun_HH(out[3],out[0],out[1],out[2],in[4],11,T[37]);
out[2] = fun_HH(out[2],out[3],out[0],out[1],in[7],16,T[38]);
out[1] = fun_HH(out[1],out[2],out[3],out[0],in[10],23,T[39]);
out[0] = fun_HH(out[0],out[1],out[2],out[3],in[13],4,T[40]);
out[3] = fun_HH(out[3],out[0],out[1],out[2],in[0],11,T[41]);
out[2] = fun_HH(out[2],out[3],out[0],out[1],in[3],16,T[42]);
out[1] = fun_HH(out[1],out[2],out[3],out[0],in[6],23,T[43]);
out[0] = fun_HH(out[0],out[1],out[2],out[3],in[9],4,T[44]);
out[3] = fun_HH(out[3],out[0],out[1],out[2],in[12],11,T[45]);
out[2] = fun_HH(out[2],out[3],out[0],out[1],in[15],16,T[46]);
out[1] = fun_HH(out[1],out[2],out[3],out[0],in[2],23,T[47]);
//fourth loop
out[0] = fun_II(out[0],out[1],out[2],out[3],in[0],6,T[48]);
out[3] = fun_II(out[3],out[0],out[1],out[2],in[7],10,T[49]);
out[2] = fun_II(out[2],out[3],out[0],out[1],in[14],15,T[50]);
out[1] = fun_II(out[1],out[2],out[3],out[0],in[5],21,T[51]);
out[0] = fun_II(out[0],out[1],out[2],out[3],in[12],6,T[52]);
out[3] = fun_II(out[3],out[0],out[1],out[2],in[3],10,T[53]);
out[2] = fun_II(out[2],out[3],out[0],out[1],in[10],15,T[54]);
out[1] = fun_II(out[1],out[2],out[3],out[0],in[1],21,T[55]);
out[0] = fun_II(out[0],out[1],out[2],out[3],in[8],6,T[56]);
out[3] = fun_II(out[3],out[0],out[1],out[2],in[15],10,T[57]);
out[2] = fun_II(out[2],out[3],out[0],out[1],in[6],15,T[58]);
out[1] = fun_II(out[1],out[2],out[3],out[0],in[13],21,T[59]);
out[0] = fun_II(out[0],out[1],out[2],out[3],in[4],6,T[60]);
out[3] = fun_II(out[3],out[0],out[1],out[2],in[11],10,T[61]);
out[2] = fun_II(out[2],out[3],out[0],out[1],in[2],15,T[62]);
out[1] = fun_II(out[1],out[2],out[3],out[0],in[9],21,T[63]);
for(i = 0; i < 4; i++)
{
out[i] += out_cpy[i];
}
}
//获取T数组
void get_T_Array(int T[64])
{
int i,tmp;
for(i = 0; i < 64; i++)
{
tmp = 1;
tmp = tmp << 16;
T[i] = (unsigned int)(fabs(sin((double)i+1)) * tmp * tmp);
}
}
//输入明文,返回密文,通过参数返回密文长度
char* MD5_fun(char* str_plain, int* o_len)
{
int len;
int len_bit;
char* str_padding;
char * str_cypher;
int len_cypher;
int len_padding;
int i;
int j;
int T[64];
int in[16];
int out[4];
char* tmp1 = (char*)malloc(64);
char* tmp2 = (char*)malloc(16);
len = strlen(str_plain); //明文长度
if(len % 64 > 56)
{
len_padding = (len/64 + 2) * 64; //补位后的长度
}
else
{
len_padding = (len/64 + 1) * 64;
}
str_padding = (char*)malloc(len_padding); //
len_cypher = len_padding / 4;
str_cypher = (char*)malloc(len_cypher);
//补位,第一个字节补80
for(i = 0; i < len; i++)
{
str_padding[i] = str_plain[i];
}
str_padding[len] = 0x80;
for(i = len+1; i < len_padding; i++)
{
str_padding[i] = 0;
}
len_bit = len * 8;//长度,已bit为单位
str_padding[len_padding-8] = len_bit ;
str_padding[len_padding-7] = len_bit >> 8;
str_padding[len_padding-6] = len_bit >> 16;
str_padding[len_padding-5] = len_bit >> 24;
get_T_Array(T);
for(i = 0; i < len_padding / 64; i++)
{
for(j = 0; j < 64; j++)
{
tmp1[j] = str_padding[i*64+j];
}
encode_c2i(tmp1,in,16); //in是16位数组,tmp1是64位数组
out[0] = 0x67452301;
out[1] = 0xefcdab89;
out[2] = 0x98badcfe;
out[3] = 0x10325476;
MD5_kerl(in,out,T);
decode_i2c(out,tmp2,4);
for(j = 0; j < 16; j++)
{
str_cypher[i*16+j] = tmp2[j];
}
}
*o_len = len_cypher;
return str_cypher;
}
int main()
{
int v1,v2,len;
int i;