#pragma	  once
//#include <afxinet.h>
#include <string>
using namespace std;

#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif

/* 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;

/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
  returns an empty list.
 */
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif

class md5 
{
private:
	typedef struct
	{
		UINT4 state[4];                                   /* state (ABCD) */
		UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
		unsigned char buffer[64];                         /* input buffer */
	} MD5_CTX;

	struct IMD5
	{
		virtual void MD5Init(MD5_CTX*) = 0;
		virtual void MD5Update(MD5_CTX*, unsigned char*, unsigned int) = 0;
		virtual void MD5Final(unsigned char[16], MD5_CTX*) = 0;

		virtual void MD5String(char* string, char* strResult) = 0;

		virtual void Release() = 0;
	};


private:
	//string _UnicodeToUtf8(CString Unicodestr);
	virtual void MD5Init(MD5_CTX*);
	virtual void MD5Update(MD5_CTX*, unsigned char*, unsigned int);
	virtual void MD5Final(unsigned char[16], MD5_CTX*);
	virtual void Release();
public:
	string StringToMD5(string str);
	//string UnicodToMD5(CString Unicodestr);
	//string Utf8ToMD5(CString Utf8str);
};