C++ MD5的源码实例详解
C++MD5源码:
md5.h:
#ifndefMD5_H #defineMD5_H #include<string> #include<fstream> /*Typedefine*/ typedefunsignedcharbyte; typedefunsignedintuint32; usingstd::string; usingstd::ifstream; /*MD5declaration.*/ classMD5{ public: MD5(); MD5(constvoid*input,size_tlength); MD5(conststring&str); MD5(ifstream&in); voidupdate(constvoid*input,size_tlength); voidupdate(conststring&str); voidupdate(ifstream&in); constbyte*digest(); stringtoString(); voidreset(); private: voidupdate(constbyte*input,size_tlength); voidfinal(); voidtransform(constbyteblock[64]); voidencode(constuint32*input,byte*output,size_tlength); voiddecode(constbyte*input,uint32*output,size_tlength); stringbytesToHexString(constbyte*input,size_tlength); /*classuncopyable*/ MD5(constMD5&); MD5&operator=(constMD5&); private: uint32_state[4];/*state(ABCD)*/ uint32_count[2];/*numberofbits,modulo2^64(low-orderwordfirst)*/ byte_buffer[64];/*inputbuffer*/ byte_digest[16];/*messagedigest*/ bool_finished;/*calculatefinished?*/ staticconstbytePADDING[64];/*paddingforcalculate*/ staticconstcharHEX[16]; staticconstsize_tBUFFER_SIZE=1024; }; #endif/*MD5_H*/
md5.cpp:
#include"md5.h" usingnamespacestd; /*ConstantsforMD5Transformroutine.*/ #defineS117 #defineS1212 #defineS1317 #defineS1422 #defineS215 #defineS229 #defineS2314 #defineS2420 #defineS314 #defineS3211 #defineS3316 #defineS3423 #defineS416 #defineS4210 #defineS4315 #defineS4421 /*F,G,HandIarebasicMD5functions. */ #defineF(x,y,z)(((x)&(y))|((~x)&(z))) #defineG(x,y,z)(((x)&(z))|((y)&(~z))) #defineH(x,y,z)((x)^(y)^(z)) #defineI(x,y,z)((y)^((x)|(~z))) /*ROTATE_LEFTrotatesxleftnbits. */ #defineROTATE_LEFT(x,n)(((x)<<(n))|((x)>>(32-(n)))) /*FF,GG,HH,andIItransformationsforrounds1,2,3,and4. Rotationisseparatefromadditiontopreventrecomputation. */ #defineFF(a,b,c,d,x,s,ac){\ (a)+=F((b),(c),(d))+(x)+ac;\ (a)=ROTATE_LEFT((a),(s));\ (a)+=(b);\ } #defineGG(a,b,c,d,x,s,ac){\ (a)+=G((b),(c),(d))+(x)+ac;\ (a)=ROTATE_LEFT((a),(s));\ (a)+=(b);\ } #defineHH(a,b,c,d,x,s,ac){\ (a)+=H((b),(c),(d))+(x)+ac;\ (a)=ROTATE_LEFT((a),(s));\ (a)+=(b);\ } #defineII(a,b,c,d,x,s,ac){\ (a)+=I((b),(c),(d))+(x)+ac;\ (a)=ROTATE_LEFT((a),(s));\ (a)+=(b);\ } constbyteMD5::PADDING[64]={0x80}; constcharMD5::HEX[16]={ '0','1','2','3', '4','5','6','7', '8','9','a','b', 'c','d','e','f' }; /*Defaultconstruct.*/ MD5::MD5(){ reset(); } /*ConstructaMD5objectwithainputbuffer.*/ MD5::MD5(constvoid*input,size_tlength){ reset(); update(input,length); } /*ConstructaMD5objectwithastring.*/ MD5::MD5(conststring&str){ reset(); update(str); } /*ConstructaMD5objectwithafile.*/ MD5::MD5(ifstream&in){ reset(); update(in); } /*Returnthemessage-digest*/ constbyte*MD5::digest(){ if(!_finished){ _finished=true; final(); } return_digest; } /*Resetthecalculatestate*/ voidMD5::reset(){ _finished=false; /*resetnumberofbits.*/ _count[0]=_count[1]=0; /*Loadmagicinitializationconstants.*/ _state[0]=0x67452301; _state[1]=0xefcdab89; _state[2]=0x98badcfe; _state[3]=0x10325476; } /*Updatingthecontextwithainputbuffer.*/ voidMD5::update(constvoid*input,size_tlength){ update((constbyte*)input,length); } /*Updatingthecontextwithastring.*/ voidMD5::update(conststring&str){ update((constbyte*)str.c_str(),str.length()); } /*Updatingthecontextwithafile.*/ voidMD5::update(ifstream&in){ if(!in) return; std::streamsizelength; charbuffer[BUFFER_SIZE]; while(!in.eof()){ in.read(buffer,BUFFER_SIZE); length=in.gcount(); if(length>0) update(buffer,length); } in.close(); } /*MD5blockupdateoperation.ContinuesanMD5message-digest operation,processinganothermessageblock,andupdatingthe context. */ voidMD5::update(constbyte*input,size_tlength){ uint32i,index,partLen; _finished=false; /*Computenumberofbytesmod64*/ index=(uint32)((_count[0]>>3)&0x3f); /*updatenumberofbits*/ if((_count[0]+=((uint32)length<<3))<((uint32)length<<3)) _count[1]++; _count[1]+=((uint32)length>>29); partLen=64-index; /*transformasmanytimesaspossible.*/ if(length>=partLen){ memcpy(&_buffer[index],input,partLen); transform(_buffer); for(i=partLen;i+63<length;i+=64) transform(&input[i]); index=0; }else{ i=0; } /*Bufferremaininginput*/ memcpy(&_buffer[index],&input[i],length-i); } /*MD5finalization.EndsanMD5message-_digestoperation,writingthe themessage_digestandzeroizingthecontext. */ voidMD5::final(){ bytebits[8]; uint32oldState[4]; uint32oldCount[2]; uint32index,padLen; /*Savecurrentstateandcount.*/ memcpy(oldState,_state,16); memcpy(oldCount,_count,8); /*Savenumberofbits*/ encode(_count,bits,8); /*Padoutto56mod64.*/ index=(uint32)((_count[0]>>3)&0x3f); padLen=(index<56)?(56-index):(120-index); update(PADDING,padLen); /*Appendlength(beforepadding)*/ update(bits,8); /*Storestateindigest*/ encode(_state,_digest,16); /*Restorecurrentstateandcount.*/ memcpy(_state,oldState,16); memcpy(_count,oldCount,8); } /*MD5basictransformation.Transforms_statebasedonblock.*/ voidMD5::transform(constbyteblock[64]){ uint32a=_state[0],b=_state[1],c=_state[2],d=_state[3],x[16]; decode(block,x,64); /*Round1*/ FF(a,b,c,d,x[0],S11,0xd76aa478);/*1*/ FF(d,a,b,c,x[1],S12,0xe8c7b756);/*2*/ FF(c,d,a,b,x[2],S13,0x242070db);/*3*/ FF(b,c,d,a,x[3],S14,0xc1bdceee);/*4*/ FF(a,b,c,d,x[4],S11,0xf57c0faf);/*5*/ FF(d,a,b,c,x[5],S12,0x4787c62a);/*6*/ FF(c,d,a,b,x[6],S13,0xa8304613);/*7*/ FF(b,c,d,a,x[7],S14,0xfd469501);/*8*/ FF(a,b,c,d,x[8],S11,0x698098d8);/*9*/ FF(d,a,b,c,x[9],S12,0x8b44f7af);/*10*/ FF(c,d,a,b,x[10],S13,0xffff5bb1);/*11*/ FF(b,c,d,a,x[11],S14,0x895cd7be);/*12*/ FF(a,b,c,d,x[12],S11,0x6b901122);/*13*/ FF(d,a,b,c,x[13],S12,0xfd987193);/*14*/ FF(c,d,a,b,x[14],S13,0xa679438e);/*15*/ FF(b,c,d,a,x[15],S14,0x49b40821);/*16*/ /*Round2*/ GG(a,b,c,d,x[1],S21,0xf61e2562);/*17*/ GG(d,a,b,c,x[6],S22,0xc040b340);/*18*/ GG(c,d,a,b,x[11],S23,0x265e5a51);/*19*/ GG(b,c,d,a,x[0],S24,0xe9b6c7aa);/*20*/ GG(a,b,c,d,x[5],S21,0xd62f105d);/*21*/ GG(d,a,b,c,x[10],S22,0x2441453);/*22*/ GG(c,d,a,b,x[15],S23,0xd8a1e681);/*23*/ GG(b,c,d,a,x[4],S24,0xe7d3fbc8);/*24*/ GG(a,b,c,d,x[9],S21,0x21e1cde6);/*25*/ GG(d,a,b,c,x[14],S22,0xc33707d6);/*26*/ GG(c,d,a,b,x[3],S23,0xf4d50d87);/*27*/ GG(b,c,d,a,x[8],S24,0x455a14ed);/*28*/ GG(a,b,c,d,x[13],S21,0xa9e3e905);/*29*/ GG(d,a,b,c,x[2],S22,0xfcefa3f8);/*30*/ GG(c,d,a,b,x[7],S23,0x676f02d9);/*31*/ GG(b,c,d,a,x[12],S24,0x8d2a4c8a);/*32*/ /*Round3*/ HH(a,b,c,d,x[5],S31,0xfffa3942);/*33*/ HH(d,a,b,c,x[8],S32,0x8771f681);/*34*/ HH(c,d,a,b,x[11],S33,0x6d9d6122);/*35*/ HH(b,c,d,a,x[14],S34,0xfde5380c);/*36*/ HH(a,b,c,d,x[1],S31,0xa4beea44);/*37*/ HH(d,a,b,c,x[4],S32,0x4bdecfa9);/*38*/ HH(c,d,a,b,x[7],S33,0xf6bb4b60);/*39*/ HH(b,c,d,a,x[10],S34,0xbebfbc70);/*40*/ HH(a,b,c,d,x[13],S31,0x289b7ec6);/*41*/ HH(d,a,b,c,x[0],S32,0xeaa127fa);/*42*/ HH(c,d,a,b,x[3],S33,0xd4ef3085);/*43*/ HH(b,c,d,a,x[6],S34,0x4881d05);/*44*/ HH(a,b,c,d,x[9],S31,0xd9d4d039);/*45*/ HH(d,a,b,c,x[12],S32,0xe6db99e5);/*46*/ HH(c,d,a,b,x[15],S33,0x1fa27cf8);/*47*/ HH(b,c,d,a,x[2],S34,0xc4ac5665);/*48*/ /*Round4*/ II(a,b,c,d,x[0],S41,0xf4292244);/*49*/ II(d,a,b,c,x[7],S42,0x432aff97);/*50*/ II(c,d,a,b,x[14],S43,0xab9423a7);/*51*/ II(b,c,d,a,x[5],S44,0xfc93a039);/*52*/ II(a,b,c,d,x[12],S41,0x655b59c3);/*53*/ II(d,a,b,c,x[3],S42,0x8f0ccc92);/*54*/ II(c,d,a,b,x[10],S43,0xffeff47d);/*55*/ II(b,c,d,a,x[1],S44,0x85845dd1);/*56*/ II(a,b,c,d,x[8],S41,0x6fa87e4f);/*57*/ II(d,a,b,c,x[15],S42,0xfe2ce6e0);/*58*/ II(c,d,a,b,x[6],S43,0xa3014314);/*59*/ II(b,c,d,a,x[13],S44,0x4e0811a1);/*60*/ II(a,b,c,d,x[4],S41,0xf7537e82);/*61*/ II(d,a,b,c,x[11],S42,0xbd3af235);/*62*/ II(c,d,a,b,x[2],S43,0x2ad7d2bb);/*63*/ II(b,c,d,a,x[9],S44,0xeb86d391);/*64*/ _state[0]+=a; _state[1]+=b; _state[2]+=c; _state[3]+=d; } /*Encodesinput(ulong)intooutput(byte).Assumeslengthis amultipleof4. */ voidMD5::encode(constuint32*input,byte*output,size_tlength){ for(size_ti=0,j=0;j<length;i++,j+=4){ output[j]=(byte)(input[i]&0xff); output[j+1]=(byte)((input[i]>>8)&0xff); output[j+2]=(byte)((input[i]>>16)&0xff); output[j+3]=(byte)((input[i]>>24)&0xff); } } /*Decodesinput(byte)intooutput(ulong).Assumeslengthis amultipleof4. */ voidMD5::decode(constbyte*input,uint32*output,size_tlength){ for(size_ti=0,j=0;j<length;i++,j+=4){ output[i]=((uint32)input[j])|(((uint32)input[j+1])<<8)| (((uint32)input[j+2])<<16)|(((uint32)input[j+3])<<24); } } /*Convertbytearraytohexstring.*/ stringMD5::bytesToHexString(constbyte*input,size_tlength){ stringstr; str.reserve(length<<1); for(size_ti=0;i<length;i++){ intt=input[i]; inta=t/16; intb=t%16; str.append(1,HEX[a]); str.append(1,HEX[b]); } returnstr; } /*Convertdigesttostringvalue*/ stringMD5::toString(){ returnbytesToHexString(digest(),16); }
测试文件test.cpp:
#include"md5.h" #include<iostream> usingnamespacestd; voidPrintMD5(conststring&str,MD5&md5){ cout<<"MD5(\""<<str<<"\")="<<md5.toString()<<endl; } stringFileDigest(conststring&file){ ifstreamin(file.c_str(),ios::binary); if(!in) return""; MD5md5; std::streamsizelength; charbuffer[1024]; while(!in.eof()){ in.read(buffer,1024); length=in.gcount(); if(length>0) md5.update(buffer,length); } in.close(); returnmd5.toString(); } intmain(){ cout<<MD5("abc").toString()<<endl; cout<<MD5(ifstream("D:\\test.txt")).toString()<<endl; cout<<MD5(ifstream("D:\\test.exe",ios::binary)).toString()<<endl; cout<<FileDigest("D:\\test.exe")<<endl; MD5md5; md5.update(""); PrintMD5("",md5); md5.update("a"); PrintMD5("a",md5); md5.update("bc"); PrintMD5("abc",md5); md5.update("defghijklmnopqrstuvwxyz"); PrintMD5("abcdefghijklmnopqrstuvwxyz",md5); md5.reset(); md5.update("messagedigest"); PrintMD5("messagedigest",md5); md5.reset(); md5.update(ifstream("D:\\test.txt")); PrintMD5("D:\\test.txt",md5); return0; }
类MD5封装了与MD5相关的操作,其有
4个构造函数:
MD5();//默认构造函数 MD5(constvoid*input,size_tlength);//输入内存地址与长度信息的构造函数 MD5(conststring&str);//输入字符串的构造函数 MD5(ifstream&in);//输入流的构造函数 3个Update函数: voidupdate(constvoid*input,size_tlength);//往MD5对象内添加内存块 voidupdate(conststring&str);//添加字符串 voidupdate(ifstream&in);//添加流 constbyte*digest();//计算MD5码,并返回指向它的指针 stringtoString();//计算MD5,并返回其对应的字符串 voidreset();//重置,
test.cpp文件内的main函数描述了MD5类的用法。
相关文章:
C++MD5源码:https://www.nhooo.com/article/103113.htm
C语言MD5源码:https://www.nhooo.com/article/103108.htm
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!