md

#include <Windows.h> //這裏面有byte類型 ,這時一個windows下面是用的庫包,利用這個庫包實現了不少函數,可是隻能在windows下用
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <math.h>
using namespace std;ios


//4個內聯函數,由於經常使用,因此提升運行效率用內聯來寫.
/*4組計算函數*/
inline unsigned int F(unsigned int X, unsigned int Y, unsigned int Z)
{
return (X & Y) | ((~X) & Z);
}
inline unsigned int G(unsigned int X, unsigned int Y, unsigned int Z)
{
return (X & Z) | (Y & (~Z));
}
inline unsigned int H(unsigned int X, unsigned int Y, unsigned int Z)
{
return X ^ Y ^ Z;
}
inline unsigned int I(unsigned int X, unsigned int Y, unsigned int Z)
{
return Y ^ (X | (~Z));
}
/*4組計算函數結束*/windows

/*32位數循環左移實現函數roll*/
void ROL(unsigned int &s, unsigned short cx)
{
if (cx > 32)cx %= 32;//寫成一行了,若是平移大於32了,就餘等32.
s = (s << cx) | (s >> (32 - cx)); //若是左邊是0,那麼就取右邊的.
return;
}數組

/*B\L互轉,接收UINT類型*/
void ltob(unsigned int &i)
{
unsigned int tmp = i;//保存副本
byte *psour = (byte*)&tmp, *pdes = (byte*)&i;
pdes += 3;//調整指針,準備左右調轉
for (short i = 3; i >= 0; --i)
{
CopyMemory(pdes - i, psour + i, 1); //表示從psour+i 這個值賦值到pdes-i這個地址,複製的長度是1.
}
return;
}函數

/*
MD5循環計算函數,label=第幾輪循環(1<=label<=4),lGroup數組=4個種子副本,M=數據(16組32位數指針)
種子數組排列方式: --A--D--C--B--,即 lGroup[0]=A; lGroup[1]=D; lGroup[2]=C; lGroup[3]=B;
*/
void AccLoop(unsigned short label, unsigned int *lGroup, void *M)
{
unsigned int *i1, *i2, *i3, *i4, TAcc, tmpi = 0; //定義:4個指針; T表累加器; 局部變量
typedef unsigned int(*clac)(unsigned int X, unsigned int Y, unsigned int Z); //定義函數類型
const unsigned int rolarray[4][4] = {
{ 7, 12, 17, 22 },
{ 5, 9, 14, 20 },
{ 4, 11, 16, 23 },
{ 6, 10, 15, 21 }
};//循環左移-位數表
const unsigned short mN[4][16] = {
{ 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 }
};//數據座標表
const unsigned int *pM = static_cast<unsigned int*>(M);//轉換類型爲32位的Uint
TAcc = ((label - 1) * 16) + 1; //根據第幾輪循環初始化T表累加器
clac clacArr[4] = { F, G, H, I }; //定義並初始化計算函數指針數組oop

/*一輪循環開始(16組->16次)*/
for (short i = 0; i < 16; ++i)
{
/*進行指針自變換*/
i1 = lGroup + ((0 + i) % 4);
i2 = lGroup + ((3 + i) % 4);
i3 = lGroup + ((2 + i) % 4);
i4 = lGroup + ((1 + i) % 4);佈局

/*第一步計算開始: A+F(B,C,D)+M[i]+T[i+1] 注:第一步中直接計算T表*/
tmpi = (*i1 + clacArr[label - 1](*i2, *i3, *i4) + pM[(mN[label - 1][i])] + (unsigned int)(0x100000000UL * abs(sin((double)(TAcc + i)))));
ROL(tmpi, rolarray[label - 1][i % 4]);//第二步:循環左移
*i1 = *i2 + tmpi;//第三步:相加並賦值到種子
}
return;
}spa

 

 

 

 

/*接口函數,並執行數據填充*/
unsigned int* MD5(const char* mStr)
{
unsigned int mLen = strlen(mStr); //計算字符串長度
if (mLen < 0) return 0;
unsigned int FillSize = 448 - ((mLen * 8) % 512); //計算需填充的bit數
unsigned int FSbyte = FillSize / 8; //以字節表示的填充數
unsigned int BuffLen = mLen + 8 + FSbyte; //緩衝區長度或者說填充後的長度
unsigned char *md5Buff = new unsigned char[BuffLen]; //分配緩衝區
CopyMemory(md5Buff, mStr, mLen); //複製字符串到緩衝區指針

/*數據填充開始*/
md5Buff[mLen] = 0x80; //第一個bit填充1
ZeroMemory(&md5Buff[mLen + 1], FSbyte - 1); //其它bit填充0,另外一可用函數爲FillMemory
unsigned long long lenBit = mLen * 8ULL; //計算字符串長度,準備填充
CopyMemory(&md5Buff[mLen + FSbyte], &lenBit, 8); //填充長度
/*數據填充結束*/接口

/*運算開始*/
unsigned int LoopNumber = BuffLen / 64; //以16個字爲一分組,計算分組數量
unsigned int A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;//初始4個種子,小端類型
unsigned int *lGroup = new unsigned int[4]{ A, D, C, B}; //種子副本數組,並做爲返回值返回
for (unsigned int Bcount = 0; Bcount < LoopNumber; ++Bcount) //分組大循環開始
{
/*進入4次計算的小循環*/
for (unsigned short Lcount = 0; Lcount < 4;)
{
AccLoop(++Lcount, lGroup, &md5Buff[Bcount * 64]);
}
/*數據相加做爲下一輪的種子或者最終輸出*/
A = (lGroup[0] += A);
B = (lGroup[3] += B);
C = (lGroup[2] += C);
D = (lGroup[1] += D);
}
/*轉換內存中的佈局後才能正常顯示*/
ltob(lGroup[0]);
ltob(lGroup[1]);
ltob(lGroup[2]);
ltob(lGroup[3]);
delete[] md5Buff; //清除內存並返回
return lGroup;
}
int main(){
char *a="dfdsasdf";
cout<<MD5(a)[0]<<endl;
cout<<MD5(a)[1]<<endl;
cout<<MD5(a)[2]<<endl;
cout<<MD5(a)[3]<<endl;
}內存

相關文章
相關標籤/搜索