c++实现MD5算法实现代码
2023-06-13 09:15:12 时间
测试结果和百度百科测试例子一致。
实现过程中需要注意事项:最后把四个变量ABCD链接成结果时,注意变量高低位的先后顺序,具体参考LinkResult()方法。
md5.h
#ifndef_MD5_H_ #define_MD5_H_ #include<iostream> #include<string> usingnamespacestd; classMD5 { public: typedefunsignedcharuchar8;//makesureitis8bit typedefcharchar8;//makesureitis8bit MD5(); voidinit(); voidUpdateMd5(constuchar8input[],constintlength); voidUpdateMd5(constchar8input[],constintlength); voidFinalize(); voidComputMd5(constuchar8input[],constintlength); voidComputMd5(constchar8input[],constintlength); stringGetMd5(); voidprintMd5(); private: typedefunsignedintuint32;//makesureitis32bit; typedefunsignedlonglonguint64;//makesureitis64bit; uint32A,B,C,D; conststaticintblockLen_=64;//512/8 //theremainafterlastupdata(becausemd5maybecomputedsegmentbysegment) uchar8remain_[blockLen_]; intremainNum_;//thenumberofremain_,<64 uint64totalInputBits_; uchar8md5Result_[16];//bitstylemd5result,totally128bit charmd5Result_hex_[33];//hexadecimalstyleresult;md5Result_hex_[32]="\0" boolisDone_;//indicatethecomputisfinished; inlineuint32RotateLeft(constuint32x,intn); inlineuint32F(constuint32x,constuint32y,constuint32z); inlineuint32G(constuint32x,constuint32y,constuint32z); inlineuint32H(constuint32x,constuint32y,constuint32z); inlineuint32I(constuint32x,constuint32y,constuint32z); inlinevoidFF(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti); inlinevoidGG(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti); inlinevoidHH(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti); inlinevoidII(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti); voidUcharToUint(uint32output[],constuchar8input[],constunsignedinttransLength); voidFourRound(constuchar8block[]); voidLinkResult(); }; /*userguide youcancomputthemd5byusingthefuntionComputMd5 eg: MD5m; MD5::char8str[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; m.ComputMd5(str,sizeof(str)-1); m.printMd5(); ifyouwanttocomputsegmentbysegment,youcandoasfollow,andinit()issuggested thebegging,andFinalize()mustcallintheend: MD5M; m.init(); MD5::uchar8str1[]="ABCDEFGHIJKLMN"; MD5::uchar8str2[]="OPQRSTUVWXYZabcdefghijk"; MD5::uchar8str3[]="lmnopqrstuvwxyz"; m.UpdateMd5(str1,sizeof(str1)-1); m.UpdateMd5(str2,sizeof(str2)-1); m.UpdateMd5(str3,sizeof(str3)-1); m.Finalize(); m.printMd5(); ifyouwanttocomputthemd5ofafile,youcanusetheinterfaceofthisprogram. */ #endif
md5.cpp
#include"md5.h" #include<iostream> usingnamespacestd; constintS[4][4]={7,12,17,22, 5,9,14,20, 4,11,16,23, 6,10,15,21}; voidMD5::init() { A=0x67452301; B=0xefcdab89; C=0x98badcfe; D=0x10325476; remainNum_=0; remain_[0]="\0"; md5Result_hex_[0]="\0"; md5Result_[0]="\0"; totalInputBits_=0; isDone_=false; } MD5::MD5() { init(); } inlineMD5::uint32MD5::RotateLeft(constuint32x,intn) { return(x<<n)|(x>>(32-n)); //ifxissigned,use:(x<<n)|((x&0xFFFFFFFF)>>(32-n)) } inlineMD5::uint32MD5::F(constuint32x,constuint32y,constuint32z) { return(x&y)|((~x)&z); } inlineMD5::uint32MD5::G(constuint32x,constuint32y,constuint32z) { return(x&z)|(y&(~z)); } inlineMD5::uint32MD5::H(constuint32x,constuint32y,constuint32z) { returnx^y^z; } inlineMD5::uint32MD5::I(constuint32x,constuint32y,constuint32z) { returny^(x|(~z)); } inlinevoidMD5::FF(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti) { a=b+RotateLeft(a+F(b,c,d)+Mj+ti,s); } inlinevoidMD5::GG(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti) { a=b+RotateLeft(a+G(b,c,d)+Mj+ti,s); } inlinevoidMD5::HH(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti) { a=b+RotateLeft(a+H(b,c,d)+Mj+ti,s); } inlinevoidMD5::II(uint32&a,constuint32b,constuint32c,constuint32d, constuint32Mj,constints,constuint32ti) { a=b+RotateLeft(a+I(b,c,d)+Mj+ti,s); } //linkABCDtoresult(bitstyleresultandhexadecimalstyleresult) voidMD5::LinkResult() { //bitstyleresult for(inti=0;i<4;i++)//linkA:lowtohigh { md5Result_[i]=(A>>8*i)&0xff; } for(inti=4;i<8;i++)//linkB:lowtohigh { md5Result_[i]=(B>>8*(i-4))&0xff; } for(inti=8;i<12;i++)//linkC:lowtohigh { md5Result_[i]=(C>>8*(i-8))&0xff; } for(inti=12;i<16;i++)//linkD:lowtohigh { md5Result_[i]=(D>>8*(i-12))&0xff; } //changetohexadecimalstyleresult //note:itisnotthesameassimplylinkhex(A)hex(B)hex(C)hex(D) for(inti=0;i<16;i++) sprintf(&md5Result_hex_[i*2],"%02x",md5Result_[i]); md5Result_hex_[32]="\0"; } //printthemd5byhex voidMD5::printMd5() { if(!isDone_) { cout<<"Error:computationisnotfinished"<<endl; } else cout<<"MD5Value:"<<md5Result_hex_<<endl; } //getthemd5valueofhexstyle stringMD5::GetMd5() { if(!isDone_) { cout<<"Error:computationisnotfinished"<<endl; exit(0); } stringa((constchar*)md5Result_hex_); returna; } voidMD5::UcharToUint(uint32output[],constuchar8input[],constunsignedinttransLength) { for(inti=0,j=0;j<transLength;i++,j+=4) { output[i]=((uint32)input[j])|(((uint32)input[j+1])<<8)| (((uint32)input[j+2])<<16)|(((uint32)input[j+3])<<24); } } //fourroundonablockof512bits; voidMD5::FourRound(constuchar8block[]) { uint32a=A,b=B,c=C,d=D; uint32M[16]; UcharToUint(M,block,blockLen_);//blockLen_isaconstint=64; //round1 FF(a,b,c,d,M[0],S[0][0],0xd76aa478); FF(d,a,b,c,M[1],S[0][1],0xe8c7b756); FF(c,d,a,b,M[2],S[0][2],0x242070db); FF(b,c,d,a,M[3],S[0][3],0xc1bdceee); FF(a,b,c,d,M[4],S[0][0],0xf57c0faf); FF(d,a,b,c,M[5],S[0][1],0x4787c62a); FF(c,d,a,b,M[6],S[0][2],0xa8304613); FF(b,c,d,a,M[7],S[0][3],0xfd469501); FF(a,b,c,d,M[8],S[0][0],0x698098d8); FF(d,a,b,c,M[9],S[0][1],0x8b44f7af); FF(c,d,a,b,M[10],S[0][2],0xffff5bb1); FF(b,c,d,a,M[11],S[0][3],0x895cd7be); FF(a,b,c,d,M[12],S[0][0],0x6b901122); FF(d,a,b,c,M[13],S[0][1],0xfd987193); FF(c,d,a,b,M[14],S[0][2],0xa679438e); FF(b,c,d,a,M[15],S[0][3],0x49b40821); //round2 GG(a,b,c,d,M[1],S[1][0],0xf61e2562); GG(d,a,b,c,M[6],S[1][1],0xc040b340); GG(c,d,a,b,M[11],S[1][2],0x265e5a51); GG(b,c,d,a,M[0],S[1][3],0xe9b6c7aa); GG(a,b,c,d,M[5],S[1][0],0xd62f105d); GG(d,a,b,c,M[10],S[1][1],0x2441453); GG(c,d,a,b,M[15],S[1][2],0xd8a1e681); GG(b,c,d,a,M[4],S[1][3],0xe7d3fbc8); GG(a,b,c,d,M[9],S[1][0],0x21e1cde6); GG(d,a,b,c,M[14],S[1][1],0xc33707d6); GG(c,d,a,b,M[3],S[1][2],0xf4d50d87); GG(b,c,d,a,M[8],S[1][3],0x455a14ed); GG(a,b,c,d,M[13],S[1][0],0xa9e3e905); GG(d,a,b,c,M[2],S[1][1],0xfcefa3f8); GG(c,d,a,b,M[7],S[1][2],0x676f02d9); GG(b,c,d,a,M[12],S[1][3],0x8d2a4c8a); //round3 HH(a,b,c,d,M[5],S[2][0],0xfffa3942); HH(d,a,b,c,M[8],S[2][1],0x8771f681); HH(c,d,a,b,M[11],S[2][2],0x6d9d6122); HH(b,c,d,a,M[14],S[2][3],0xfde5380c); HH(a,b,c,d,M[1],S[2][0],0xa4beea44); HH(d,a,b,c,M[4],S[2][1],0x4bdecfa9); HH(c,d,a,b,M[7],S[2][2],0xf6bb4b60); HH(b,c,d,a,M[10],S[2][3],0xbebfbc70); HH(a,b,c,d,M[13],S[2][0],0x289b7ec6); HH(d,a,b,c,M[0],S[2][1],0xeaa127fa); HH(c,d,a,b,M[3],S[2][2],0xd4ef3085); HH(b,c,d,a,M[6],S[2][3],0x4881d05); HH(a,b,c,d,M[9],S[2][0],0xd9d4d039); HH(d,a,b,c,M[12],S[2][1],0xe6db99e5); HH(c,d,a,b,M[15],S[2][2],0x1fa27cf8); HH(b,c,d,a,M[2],S[2][3],0xc4ac5665); //round4 II(a,b,c,d,M[0],S[3][0],0xf4292244); II(d,a,b,c,M[7],S[3][1],0x432aff97); II(c,d,a,b,M[14],S[3][2],0xab9423a7); II(b,c,d,a,M[5],S[3][3],0xfc93a039); II(a,b,c,d,M[12],S[3][0],0x655b59c3); II(d,a,b,c,M[3],S[3][1],0x8f0ccc92); II(c,d,a,b,M[10],S[3][2],0xffeff47d); II(b,c,d,a,M[1],S[3][3],0x85845dd1); II(a,b,c,d,M[8],S[3][0],0x6fa87e4f); II(d,a,b,c,M[15],S[3][1],0xfe2ce6e0); II(c,d,a,b,M[6],S[3][2],0xa3014314); II(b,c,d,a,M[13],S[3][3],0x4e0811a1); II(a,b,c,d,M[4],S[3][0],0xf7537e82); II(d,a,b,c,M[11],S[3][1],0xbd3af235); II(c,d,a,b,M[2],S[3][2],0x2ad7d2bb); II(b,c,d,a,M[9],S[3][3],0xeb86d391); A+=a; B+=b; C+=c; D+=d; } //updatemd5,mustconsidertheremain_. voidMD5::UpdateMd5(constuchar8input[],constintlength) { isDone_=false; totalInputBits_+=(length<<3); intstart=blockLen_-remainNum_;//blockLen_=64 //copyapartofinputtoremain_soitcanformablock(size=64) if(start<=length) { //canformablock,thendoFourRoundtothisblock memcpy(&remain_[remainNum_],input,start); FourRound(remain_); inti; for(i=start;i<=length-blockLen_;i+=blockLen_) { FourRound(&input[i]); } remainNum_=length-i; memcpy(remain_,&input[i],remainNum_); } else { //cannotformablock,functionreturn; memcpy(&remain_[remainNum_],input,length); remainNum_+=length; } } voidMD5::UpdateMd5(constchar8input[],constintlength) { UpdateMd5((constuchar8*)input,length); } //paddingwith100000...toremain_andaddthe64bitoriginalsizeofinput voidMD5::Finalize() { if(isDone_==true) return; uchar8padding[64]={ 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; inttemp=56-remainNum_;//56=448/8 if(temp>0) { UpdateMd5(padding,temp); totalInputBits_-=(temp<<3); } elseif(temp<0) { UpdateMd5(padding,64+temp); totalInputBits_-=((64+temp)<<3); } //transtotalInputBits_touchar8(64bits) uchar8Bits[8]; for(inti=0;i<8;i++) { Bits[i]=(totalInputBits_>>8*i)&0xff; } UpdateMd5(Bits,8);//addthenumberoforiginalinput(thelast64bits) LinkResult(); isDone_=true; } //computthemd5basedoninput,(justthisoneinput) voidMD5::ComputMd5(constuchar8input[],constintlength) { init(); UpdateMd5(input,length); Finalize(); } voidMD5::ComputMd5(constchar8input[],constintlength) { ComputMd5((constuchar8*)input,length); }
相关文章
- C++STL初识,概念、六大组件、容器算法迭代器
- 手眼标定算法Tsai-Lenz代码实现(Python、C++、Matlab)
- 二叉树层次遍历算法——C/C++
- C++ lamda表达式[通俗易懂]
- c++ access函数_Linux中GCC编译C程序过程
- C++——随机数算法
- 现代c++中实现精确延时方法总结
- Dijkstra(迪杰斯特拉算法)的实现-------------------------C,C++,Matlab实现
- WMI Based System Share Detect Via C/C++
- C++ STL 标准模板库(排序/集合/适配器)算法
- C/C++ 反汇编:关于Switch语句的优化措施
- C/C++ Capstone 引擎源码编译
- [C++STL教程]4.map超强的容器,它终于来了!零基础都能理解的入门教程
- 【C++修炼之路】28.新的类功能
- C++ const成员和引用成员
- c++二叉树的几种遍历算法
- C++基本算法冒泡法、交换法、选择法、实现代码集合
- 浅析C++中模板的那点事
- 探讨register关键字在c语言和c++中的差异
- C++中函数的默认参数详细解析
- C++中函数模板的用法详细解析
- c++读取sqlserver示例分享
- c++非变易算法-stl算法
- C++实现一维向量旋转算法
- C++对数组的引用实例分析