閒着沒事幹,索性實現一下MD5
具體的東西,說白了,就是把原始數據+補充數據共分割成N個64位的小段,每個小段又分成16個小節,然後每個小段參與一次四輪運算,用ABCD這四個數關聯起他們,保證數據有絲毫變動,得到的MD5碼,會完全變動。
F=(x&y)|((~x)&z)
G=(x&z)|(y&(~z))
H=x^y^z
I=y^(x|(~z))
FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)
GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<<s)
HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)
II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)
unsigned int A=0x67452301UL;
unsigned int B=0xEFCDAB89UL;
unsigned int C=0x98BADCFEUL;
unsigned int D=0x10325476UL;
四輪循環N次,每i次取第i個分割裏的m[16]參與運算,最後得到ABCD四個值,A佔4個字節,記爲A1A2A3A4
最後按A4A3A2A1B4B3B2B1C4C3C2C1D4D3D2D1取16進制輸出即得到md5碼
//四輪循環
{
a=A;
b=B;
c=C
d=D;
FF(a,b,c,d,m[0],7,0xd76aa478);//a,b,c,d不用解釋,m[0]是每個分割出來的64字節段的其中32位的一塊,7任意數,0xd76aa478是(2^32)*abs()
FF(d,a,b,c,m[1],12,0xe8c7b756);
FF(c,d,a,b,m[2],17,0x242070db);
FF(b,c,d,a,m[3],22,0xc1bdceee);
FF(a,b,c,d,m4],7,0xf57c0faf);
FF(d,a,b,c,m[5],12,0x4787c62a);
FF(c,d,a,b,m[6],17,0xa8304613);
FF(b,c,d,a,m[7],22,0xfd469501) ;
FF(a,b,c,d,m[8],7,0x698098d8) ;
FF(d,a,b,c,m[9],12,0x8b44f7af) ;
FF(c,d,a,b,m[10],17,0xffff5bb1) ;
FF(b,c,d,a,m[11],22,0x895cd7be) ;
FF(a,b,c,d,m[12],7,0x6b901122) ;
FF(d,a,b,c,m[13],12,0xfd987193) ;
FF(c,d,a,b,m[14],17,0xa679438e) ;
FF(b,c,d,a,m[15],22,0x49b40821);
GG(a,b,c,d,m[1],5,0xf61e2562);
GG(d,a,b,c,m[6],9,0xc040b340);
GG(c,d,a,b,m[11],14,0x265e5a51);
GG(b,c,d,a,m[0],20,0xe9b6c7aa) ;
GG(a,b,c,d,m[5],5,0xd62f105d) ;
GG(d,a,b,c,m[10],9,0x02441453) ;
GG(c,d,a,b,m[15],14,0xd8a1e681);
GG(b,c,d,a,m[4],20,0xe7d3fbc8) ;
GG(a,b,c,d,m[9],5,0x21e1cde6) ;
GG(d,a,b,c,m[14],9,0xc33707d6) ;
GG(c,d,a,b,m[3],14,0xf4d50d87) ;
GG(b,c,d,a,m[8],20,0x455a14ed);
GG(a,b,c,d,m[13],5,0xa9e3e905);
GG(d,a,b,c,m[2],9,0xfcefa3f8) ;
GG(c,d,a,b,m[7],14,0x676f02d9) ;
GG(b,c,d,a,m[12],20,0x8d2a4c8a);
HH(a,b,c,d,m[5],4,0xfffa3942);
HH(d,a,b,c,m[8],11,0x8771f681);
HH(c,d,a,b,m[11],16,0x6d9d6122);
HH(b,c,d,a,m[14],23,0xfde5380c) ;
HH(a,b,c,d,m[1],4,0xa4beea44) ;
HH(d,a,b,c,m[4],11,0x4bdecfa9) ;
HH(c,d,a,b,m[7],16,0xf6bb4b60) ;
HH(b,c,d,a,m[10],23,0xbebfbc70);
HH(a,b,c,d,m[13],4,0x289b7ec6);
HH(d,a,b,c,m[0],11,0xeaa127fa);
HH(c,d,a,b,m[3],16,0xd4ef3085);
HH(b,c,d,a,m[6],23,0x04881d05);
HH(a,b,c,d,m[9],4,0xd9d4d039);
HH(d,a,b,c,m[12],11,0xe6db99e5);
HH(c,d,a,b,m[15],16,0x1fa27cf8) ;
HH(b,c,d,a,m[2],23,0xc4ac5665);
II(a,b,c,d,m[0],6,0xf4292244)
;
II(d,a,b,c,m[7],10,0x432aff97) ;
II(c,d,a,b,m[14],15,0xab9423a7);
II(b,c,d,a,m[5],21,0xfc93a039) ;
II(a,b,c,d,m[12],6,0x655b59c3) ;
II(d,a,b,c,m[3],10,0x8f0ccc92) ;
II(c,d,a,b,m[10],15,0xffeff47d);
II(b,c,d,a,m[1],21,0x85845dd1) ;
II(a,b,c,d,m[8],6,0x6fa87e4f) ;
II(d,a,b,c,m[15],10,0xfe2ce6e0);
II(c,d,a,b,m[6],15,0xa3014314) ;
II(b,c,d,a,m[13],21,0x4e0811a1);
II(a,b,c,d,m[4],6,0xf7537e82) ;
II(d,a,b,c,m[11],10,0xbd3af235);
II(c,d,a,b,m[2],15,0x2ad7d2bb);
II(b,c,d,a,m[9],21,0xeb86d391);
A+=a; B+=b; C+=c; D+=d;
}
附上代碼。代碼還有很多問題。但是懶得改了,。。湊合看吧
typedef unsigned int uint;
class MD5
{
public:
MD5(char *str=NULL);
unsigned char* GET(){return MD;}
void PUT();
uint F(uint x,uint y,uint z){return (x&y)|((~x)&z);}
uint G(uint x,uint y,uint z){return (x&z)|(y&(~z));}
uint H(uint x,uint y,uint z){return x^y^z;}
uint I(uint x,uint y,uint z){return y^(x|(~z));}
uint FF(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
uint GG(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
uint HH(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
uint II(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt);
uint mov(uint x,int ss){};
private:
int N,M;
static uint t[64];//值爲4294967295*abs(sin(i))的整數部分
static int s[16];//循環左移s
uint **p;
uint A,B,C,D;
uint a,b,c,d;
unsigned char MD[16];
};
// FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)
// GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<<s)
// HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)
// II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)
void MD5::PUT()
{
for(int i=0;i<16;i++)
printf("%x",MD[i]);
cout<<endl;
}
uint MD5::FF(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
uint mid,qut;
mid=a+F(b,c,d)+m+tt;
qut=mid;
mid>>=(32-tt);
qut<<=tt;
qut^=mid;
a=b+qut;
return a;
}
uint MD5::GG(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
uint mid,qut;
mid=a+F(b,c,d)+m+tt;
qut=mid;
mid>>=(32-tt);
qut<<=tt;
qut^=mid;
a=b+qut;
return a;
}
uint MD5::HH(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
uint mid,qut;
mid=a+F(b,c,d)+m+tt;
qut=mid;
mid>>=(32-tt);
qut<<=tt;
qut^=mid;
a=b+qut;
return a;
}
uint MD5::II(uint &a,uint &b,uint &c,uint &d,uint m,int ss,uint tt)
{
uint mid,qut;
mid=a+F(b,c,d)+m+tt;
qut=mid;
mid>>=(32-tt);
qut<<=tt;
qut^=mid;
a=b+qut;
return a;
}
MD5::MD5(char *str)
{
A=0x67452301UL;
B=0xEFCDAB89UL;
C=0x98BADCFEUL;
D=0x10325476UL;
int m=strlen(str),z=0;
N=m/64+1;
M=m%64;
/*-----------------分配內存-----------------*/
p=new uint*[N];
for(int i=0;i<N;i++)
p[i]=new uint[16];
for(int i=0;i<N;i++)
for(int j=0;j<16;j++)
p[i][j]=0;
/*-----------------構造分組---------------*/
for(int i=0;i<N;i++)
{
for(int j=0;j<64;j++)
{
if(z==m)
{
p[i][j/4]<<=8;
p[i][j/4]^=128;
for(;j<64;j++)
p[i][j/4]<<=8;
break;
}
p[i][j/4]<<=8;
p[i][j/4]^=str[z++];
}
}
/*------------------四輪運算-------------------*/
for(int i=0;i<N;i++)
{
a=A;
b=B;
c=C;
d=D;
for(int j=0;j<16;j++)
{
FF(a,b,c,d,p[i][j],s[i],t[16*i+j]);
uint o=a;
a=b;
b=c;
c=d;
d=o;
}
for(int j=0;j<16;j++)
{
GG(a,b,c,d,p[i][j],s[i],t[16*i+j]);
uint o=a;
a=b;
b=c;
c=d;
d=o;
}
for(int j=0;j<16;j++)
{
HH(a,b,c,d,p[i][j],s[i],t[16*i+j]);
uint o=a;
a=b;
b=c;
c=d;
d=o;
}
for(int j=0;j<16;j++)
{
II(a,b,c,d,p[i][j],s[i],t[16*i+j]);
uint o=a;
a=b;
b=c;
c=d;
d=o;
}
A+=a;
B+=b;
C+=c;
D+=d;
// cout<<"A="<<A<<endl;
// cout<<"B="<<B<<endl;
// cout<<"C="<<C<<endl;
// cout<<"D="<<D<<endl;
}
/*---------------四輪運算完成--------------*/
/*---------------構造MD5輸出碼----------------*/
int i;
for(i=0;i<4;i++)
{
MD[i]=MD[i+4]=MD[i+8]=MD[i+12]=0;
MD[i]=MD[i]^(A>>(i*8));
MD[i+4]=MD[i+4]^(B>>(i*8));
MD[i+8]=MD[i+8]^(C>>(i*8));
MD[i+12]=MD[i+12]^(D>>(i*8));
}
// cout<<"A="<<A<<endl;
// cout<<"B="<<B<<endl;
// cout<<"C="<<C<<endl;
// cout<<"D="<<D<<endl;
}
uint MD5::t[64]={
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
0x6b901122,0xfd987193,0xa679438e,0x49b40821,
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391
};
int MD5::s[16]={
7,12,17,22,
5,9,14,20,
4,11,16,32,
6,10,15,21
};