C++ MD5的源码实例详解

C++ MD5源码:

md5.h:

#ifndef MD5_H
#define MD5_H 

#include <string>
#include <fstream> 

/* Type define */
typedef unsigned char byte;
typedef unsigned int uint32; 

using std::string;
using std::ifstream; 

/* MD5 declaration. */
class MD5 {
public:
 MD5();
 MD5(const void *input, size_t length);
 MD5(const string &str);
 MD5(ifstream &in);
 void update(const void *input, size_t length);
 void update(const string &str);
 void update(ifstream &in);
 const byte* digest();
 string toString();
 void reset();
private:
 void update(const byte *input, size_t length);
 void final();
 void transform(const byte block[64]);
 void encode(const uint32 *input, byte *output, size_t length);
 void decode(const byte *input, uint32 *output, size_t length);
 string bytesToHexString(const byte *input, size_t length); 

 /* class uncopyable */
 MD5(const MD5&);
 MD5& operator=(const MD5&);
private:
 uint32 _state[4]; /* state (ABCD) */
 uint32 _count[2]; /* number of bits, modulo 2^64 (low-order word first) */
 byte _buffer[64]; /* input buffer */
 byte _digest[16]; /* message digest */
 bool _finished; /* calculate finished ? */ 

 static const byte PADDING[64]; /* padding for calculate */
 static const char HEX[16];
 static const size_t BUFFER_SIZE = 1024;
}; 

#endif/*MD5_H*/

md5.cpp:

#include "md5.h" 

using namespace std; 

/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21 

/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z))) 

/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
 (a) += F ((b), (c), (d)) + (x) + ac; \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
 (a) += G ((b), (c), (d)) + (x) + ac; \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
 (a) += H ((b), (c), (d)) + (x) + ac; \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
 (a) += I ((b), (c), (d)) + (x) + ac; \
 (a) = ROTATE_LEFT ((a), (s)); \
 (a) += (b); \
} 

const byte MD5::PADDING[64] = { 0x80 };
const char MD5::HEX[16] = {
 '0', '1', '2', '3',
 '4', '5', '6', '7',
 '8', '9', 'a', 'b',
 'c', 'd', 'e', 'f'
}; 

/* Default construct. */
MD5::MD5() {
 reset();
} 

/* Construct a MD5 object with a input buffer. */
MD5::MD5(const void *input, size_t length) {
 reset();
 update(input, length);
} 

/* Construct a MD5 object with a string. */
MD5::MD5(const string &str) {
 reset();
 update(str);
} 

/* Construct a MD5 object with a file. */
MD5::MD5(ifstream &in) {
 reset();
 update(in);
} 

/* Return the message-digest */
const byte* MD5::digest() {
 if (!_finished) {
 _finished = true;
 final();
 }
 return _digest;
} 

/* Reset the calculate state */
void MD5::reset() { 

 _finished = false;
 /* reset number of bits. */
 _count[0] = _count[1] = 0;
 /* Load magic initialization constants. */
 _state[0] = 0x67452301;
 _state[1] = 0xefcdab89;
 _state[2] = 0x98badcfe;
 _state[3] = 0x10325476;
} 

/* Updating the context with a input buffer. */
void MD5::update(const void *input, size_t length) {
 update((const byte*)input, length);
} 

/* Updating the context with a string. */
void MD5::update(const string &str) {
 update((const byte*)str.c_str(), str.length());
} 

/* Updating the context with a file. */
void MD5::update(ifstream &in) { 

 if (!in)
 return; 

 std::streamsize length;
 char buffer[BUFFER_SIZE];
 while (!in.eof()) {
 in.read(buffer, BUFFER_SIZE);
 length = in.gcount();
 if (length > 0)
  update(buffer, length);
 }
 in.close();
} 

/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5::update(const byte *input, size_t length) { 

 uint32 i, index, partLen; 

 _finished = false; 

 /* Compute number of bytes mod 64 */
 index = (uint32)((_count[0] >> 3) & 0x3f); 

 /* update number of bits */
 if((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3))
 _count[1]++;
 _count[1] += ((uint32)length >> 29); 

 partLen = 64 - index; 

 /* transform as many times as possible. */
 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;
 } 

 /* Buffer remaining input */
 memcpy(&_buffer[index], &input[i], length-i);
} 

/* MD5 finalization. Ends an MD5 message-_digest operation, writing the
the message _digest and zeroizing the context.
*/
void MD5::final() { 

 byte bits[8];
 uint32 oldState[4];
 uint32 oldCount[2];
 uint32 index, padLen; 

 /* Save current state and count. */
 memcpy(oldState, _state, 16);
 memcpy(oldCount, _count, 8); 

 /* Save number of bits */
 encode(_count, bits, 8); 

 /* Pad out to 56 mod 64. */
 index = (uint32)((_count[0] >> 3) & 0x3f);
 padLen = (index < 56) ? (56 - index) : (120 - index);
 update(PADDING, padLen); 

 /* Append length (before padding) */
 update(bits, 8); 

 /* Store state in digest */
 encode(_state, _digest, 16); 

 /* Restore current state and count. */
 memcpy(_state, oldState, 16);
 memcpy(_count, oldCount, 8);
} 

/* MD5 basic transformation. Transforms _state based on block. */
void MD5::transform(const byte block[64]) { 

 uint32 a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16]; 

 decode(block, x, 64); 

 /* Round 1 */
 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 */ 

 /* Round 2 */
 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 */ 

 /* Round 3 */
 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 */ 

 /* Round 4 */
 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;
} 

/* Encodes input (ulong) into output (byte). Assumes length is
a multiple of 4.
*/
void MD5::encode(const uint32 *input, byte *output, size_t length) { 

 for(size_t i=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);
 }
} 

/* Decodes input (byte) into output (ulong). Assumes length is
a multiple of 4.
*/
void MD5::decode(const byte *input, uint32 *output, size_t length) { 

 for(size_t i=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);
 }
} 

/* Convert byte array to hex string. */
string MD5::bytesToHexString(const byte *input, size_t length) {
 string str;
 str.reserve(length << 1);
 for(size_t i = 0; i < length; i++) {
 int t = input[i];
 int a = t / 16;
 int b = t % 16;
 str.append(1, HEX[a]);
 str.append(1, HEX[b]);
 }
 return str;
} 

/* Convert digest to string value */
string MD5::toString() {
 return bytesToHexString(digest(), 16);
}

测试文件test.cpp:

#include "md5.h"
#include <iostream> 

using namespace std; 

void PrintMD5(const string &str, MD5 &md5) {
 cout << "MD5(\"" << str << "\") = " << md5.toString() << endl;
} 

string FileDigest(const string &file) { 

 ifstream in(file.c_str(), ios::binary);
 if (!in)
 return ""; 

 MD5 md5;
 std::streamsize length;
 char buffer[1024];
 while (!in.eof()) {
 in.read(buffer, 1024);
 length = in.gcount();
 if (length > 0)
  md5.update(buffer, length);
 }
 in.close();
 return md5.toString();
} 

int main() { 

 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; 

 MD5 md5;
 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("message digest");
 PrintMD5("message digest", md5); 

 md5.reset();
 md5.update(ifstream("D:\\test.txt"));
 PrintMD5("D:\\test.txt", md5);
 return 0;
}

类MD5封装了与MD5相关的操作,其有

4个构造函数:

MD5();          //默认构造函数
MD5(const void *input, size_t length);   //输入内存地址与长度信息的构造函数
MD5(const string &str);      //输入字符串的构造函数
MD5(ifstream &in);       //输入流的构造函数
3个Update函数:
void update(const void *input, size_t length); //往MD5对象内添加内存块
void update(const string &str);    //添加字符串
void update(ifstream &in);     //添加流

const byte* digest();       //计算MD5码,并返回指向它的指针
string toString();       //计算MD5,并返回其对应的字符串
void reset();        //重置,

test.cpp文件内的main函数描述了MD5类的用法。

相关文章:

C++ MD5源码:http://www.jb51.net/article/103113.htm

C语言 MD5源码:http://www.jb51.net/article/103108.htm

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Java与C++实现相同的MD5加密算法简单实例

    1.Java版 package com.lyz.utils.common; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * MD5加密 * @author liuyazhuang */ public class MD5Hash { public static String md5

  • C/C++ MD5算法的实现代码

    在逆向程序的时候,经常会碰到加密的算法的问题,前面分析UC的逆向工程师的面试题2的时候,发现使用了MD5的加密算法(MD5算法是自己实现的,不是使用的算法库函数).尤其是在逆向分析网络协议的时候,一般的程序使用的加密算法都是使用的库函数提供的算法,有些程序使用的算法是自己实现的:相对来说使用函数库提供的加密函数的算法相对来说比较好识别,因为有算法常见函数在:但是如果不是使用的函数库提供的加密的函数而是自己去实现某些算法话,识别起来有一定的难度,这就需要你对函数的加密原理以及流程还算法的特征比较熟

  • VC++ 字符串String MD5计算小工具 VS2008工程

    基于字符串加密的MD5算法,VS2008 VC++,多字节编译工程.主要代码如下,实现了ANSI字符串加密与Unicode字符串加密. 运行效果如下: 核心代码: void CEncryptByMd5Dlg::OnButtonOk() { // TODO: Add your control notification handler code here UpdateData(true); unsigned int len=0; char *cTemp =NULL; if(m_bType==0) {

  • c++实现MD5算法实现代码

    测试结果和百度百科测试例子一致. 实现过程中需要注意事项:最后把四个变量A B C D 链接成结果时 ,注意变量高低位的先后顺序,具体参考 LinkResult()方法. md5.h #ifndef _MD5_H_ #define _MD5_H_ #include <iostream> #include <string> using namespace std; class MD5 { public: typedef unsigned char uchar8; //make sur

  • C++中md5 算法实现代码

    在网上找了份c++ MD5的代码,就简单保存一下: 首先md5.h #ifndef MD5_H #define MD5_H #include <string> #include <fstream> /* Type define */ typedef unsigned char byte; typedef unsigned long ulong; using std::string; using std::ifstream; /* MD5 declaration. */ class

  • C语言 MD5的源码实例详解

    C语言 MD5源码 md5c.h: /* POINTER defines a generic pointer type */ typedef unsigned char * POINTER; /* UINT2 defines a two byte word */ //typedef unsigned short int UINT2; /* UINT4 defines a four byte word */ typedef unsigned long int UINT4; /* MD5 conte

  • C++ MD5的源码实例详解

    C++ MD5源码: md5.h: #ifndef MD5_H #define MD5_H #include <string> #include <fstream> /* Type define */ typedef unsigned char byte; typedef unsigned int uint32; using std::string; using std::ifstream; /* MD5 declaration. */ class MD5 { public: MD

  • springboot自动扫描添加的BeanDefinition源码实例详解

    1. springboot启动过程中,首先会收集需要加载的bean的定义,作为BeanDefinition对象,添加到BeanFactory中去. 由于BeanFactory中只有getBean之类获取bean对象的方法,所以将将BeanDefinition添加到BeanFactory中,是通过BeanDefinitionRegistry接口的void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) t

  • Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码)实例详解

    1.Python requests模块说明 requests是使用Apache2 licensed 许可证的HTTP库. 用python编写. 比urllib2模块更简洁. Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码. 在python内置模块的基础上进行了高度的封装,从而使得python进行网络请求时,变得人性化,使用Requests可以轻而易举的完成浏览器可有的任何操作. 现代,国际化

  • Android通过访问网页查看网页源码实例详解

    Android通过访问网页查看网页源码 1.添加网络权限 <!--访问网络的权限--> <uses-permission android:name="android.permission.INTERNET"/> 2.获取网络中网页的数据 /** * 获取网页HTML源代码 * @param path 网页路径 */ public static String getHtml(String path) throws Exception { URL url=new U

  • IOS身份证识别(OCR源码)详解及实例代码

    IOS身份证识别(OCR源码)详解 最近项目用到身份证识别,在github上搜了一堆demo,在Google上找了一堆代码,有能识别出证件照的,但是都是打包成.a的静态库,没有源码,我努力吃了几天书,有了一点研究成果,现在贴出来与大家分享,要是有更好的方法,希望大神指正,共同探讨解决方案.(以下代码本人亲测可用,正在进一步探索智能识别,如有兴趣,请加入) 这里用到了两个开源库:OpenCV.TesseractOCRiOS,两个语言包chi_sim.eng.身份证识别的流程主要有:灰度化,阀值二值

  • Python日志打印里logging.getLogger源码分析详解

    实践环境 WIN 10 Python 3.6.5 函数说明 logging.getLogger(name=None) getLogger函数位于logging/__init__.py脚本 源码分析 _loggerClass = Logger # ...略 root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) # ...略 def getLogger(name=None): "&quo

  • Vue之vue.$set()方法源码案例详解

    在使用vue开发项目的过程中,经常会遇到这样的问题:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的. 这是因为新加入的属性不是响应式的,因此不会触发视图的更新,通常使用静态方法Vue.set()或者实例方法this.$set()解决 ,使用方式: 对象:this.$set(target,key,  value) 数组:this.$set(target,index,  value) 但不管是静态方法Vue.

  • Android Handler,Message,MessageQueue,Loper源码解析详解

    本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文< Android中Handler的使用>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功能.但

  • React commit源码分析详解

    目录 总览 commitBeforeMutationEffects commitMutationEffects 插入 dom 节点 获取父节点及插入位置 判断当前节点是否为单节点 在对应位置插入节点 更新 dom 节点 更新 HostComponent 更新 HostText 删除 dom 节点 unmountHostComponents commitNestedUnmounts commitUnmount commitLayoutEffects 执行生命周期 处理回调 总结 总览 commit

随机推荐