Windows平台下面的MD5算法

Windows的SDK提供了MD5的算法,但没有提供.h方式的调用方式,需要动态加载DLL。

 

本文是C++方式的封装,主要涉及2个类:MD5和MD5Impl。前者是用户接口,后者是具体实现。提供2个class的原因在于屏蔽MD5用到的数据结构,简化调用方式。

 

MD5.h

#ifndef __MD5_H
#define __MD5_H

class MD5Impl;

class MD5
{
public:
	MD5();
	~MD5();

	void Init();
	void Update(unsigned char* buffer, unsigned int inlen);
	void Final();
	void GetDigest(unsigned char digest[]);

private:
	MD5Impl* m_pImpl;
};

#endif


 

MD5.cpp

#include "MD5.h"
#include "MD5Impl.h"

MD5::MD5():m_pImpl(new MD5Impl())
{
}

MD5::~MD5()
{
	delete m_pImpl;
}


void MD5::Init()
{
	m_pImpl->Init();
}

void MD5::Update(unsigned char* buffer, unsigned int inlen)
{
	m_pImpl->Update(buffer, inlen);
}

void MD5::Final()
{
	m_pImpl->Final();
}

void MD5::GetDigest(unsigned char digest[])
{
	m_pImpl->GetDigest(digest);
}


 

MD5Impl.h

#ifndef __MD5IMPL_H
#define __MD5IMPL_H

#include <windows.h>

typedef struct {  
	ULONG i[2];
	ULONG buf[4];
	unsigned char in[64];
	unsigned char digest[16];
} MD5_CONTEXT;

typedef void (WINAPI* TypeMD5Init) (MD5_CONTEXT *);  
typedef void (WINAPI* TypeMD5Update) (MD5_CONTEXT *, const unsigned char *, unsigned int);  
typedef void (WINAPI* TypeMD5Final) (MD5_CONTEXT *);  


class MD5Impl
{
public:
	MD5Impl();
	~MD5Impl();

	bool Init();
	void Update(unsigned char* buffer, unsigned int inlen);
	void Final();
	void GetDigest(unsigned char digest[]);

private:
	bool Load();

private:
	MD5_CONTEXT m_context;
	HMODULE m_hDLL;
	TypeMD5Init m_fMD5Init;
	TypeMD5Update m_fMD5Update;
	TypeMD5Final m_fMD5Final;
};

#endif


 

MD5Impl.cpp

#include "MD5Impl.h"

#include <cassert>

MD5Impl::MD5Impl()
:m_context(), m_hDLL(NULL), m_fMD5Init(NULL), m_fMD5Update(NULL), m_fMD5Final(NULL)
{
}

MD5Impl::~MD5Impl()
{
	if (m_hDLL) {
		FreeLibrary(m_hDLL);
		m_hDLL = NULL;
		m_fMD5Init = NULL;
		m_fMD5Update = NULL;
		m_fMD5Final = NULL;
	}
}

bool MD5Impl::Init()
{
	if (NULL ==m_hDLL) {
		if (!Load()) return false;
	}

	m_fMD5Init(&m_context);
	return true;
}

void MD5Impl::Update(unsigned char* buffer, unsigned int inlen)
{
	if (NULL == m_hDLL) return;

	m_fMD5Update(&m_context, buffer, inlen);
}

void MD5Impl::Final()
{
	if (NULL == m_hDLL) return;

	m_fMD5Final(&m_context);
}

void MD5Impl::GetDigest(unsigned char digest[])
{
	if (NULL == m_hDLL) return;

	memcpy(digest, m_context.digest, 16);
}


bool MD5Impl::Load()
{
	assert(NULL == m_hDLL);

	m_hDLL = LoadLibrary("advapi32.dll");
	if (NULL == m_hDLL) return false;

	m_fMD5Init = (TypeMD5Init)GetProcAddress(m_hDLL, "MD5Init");
	m_fMD5Update = (TypeMD5Update)GetProcAddress(m_hDLL, "MD5Update");
	m_fMD5Final = (TypeMD5Final)GetProcAddress(m_hDLL, "MD5Final");

	return true;
}


 

辅助类StringUtility

 

#include "StringUtility.h"

#include <cstdio>
void StringUtility::DumpHex(const unsigned char* buffer, unsigned int len)
{
	if (NULL == buffer) return;

	for (unsigned int i = 0; i < len; i++) {
		printf("%02X ", buffer[i]);
	}
	printf("\n");
}


 

测试代码:

 

#include <cstdio>
#include <cstring>
#include "MD5.h"
#include "StringUtility.h"

int main()
{
	const char* s = "Hello, world!";

	MD5 md5;
	md5.Init();
	md5.Update((unsigned char*)s, strlen(s));
	md5.Final();

	unsigned char digest[16] = {0};
	md5.GetDigest(digest);

	StringUtility::DumpHex(digest, 16);
	return 0;
}


 

运行结果:

6C D3 55 6D EB 0D A5 4B CA 06 0B 4C 39 47 98 39
请按任意键继续. . .


 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值