// Base64.h: interface for the Base64 class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_BASE64_H__D1CE45BE_2DDD_47A2_9777_CA3BA8A42AE4__INCLUDED_)
#define AFX_BASE64_H__D1CE45BE_2DDD_47A2_9777_CA3BA8A42AE4__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <afx.h>
class Base64
{
public:
// 将ANSI字符串转成Base64字符串
static CString encode(const CString in_str);
static void encode(LPSTR pIn, DWORD dwInLen, LPSTR pOut, LPDWORD pdwOutLen);
// 将Base64字符串转成ANSI字符串
static CString decode(const CString in_str);
static void decode(LPSTR pIn, DWORD dwInLen, LPSTR pOut, LPDWORD pdwOutLen);
// 将ANSI格式文件转成Base64格式文件
static BOOL encode(const CString cstrSrc, const CString cstrDes);
static BOOL encodeMemMap(LPCTSTR fIn, LPCTSTR fOut);
// 将Base64格式文件转成ANSI格式文件
static BOOL decode(const CString cstrSrc, const CString cstrDes);
static BOOL decodeMemMap(LPCTSTR fIn, LPCTSTR fOut);
static inline PSTR AllocMemBase64(DWORD dwANSILen);
static inline PSTR AllocMemANSI(DWORD dwBase64Len);
static inline void FreeMemBase64(PSTR pBase64);
static inline void FreeMemANSI(PSTR pANSI);
protected:
static inline DWORD CalcANSItoBase64Len(DWORD dwANSILen);
static inline DWORD CalcBase64toANSILen(DWORD dwBase64Len, const CString strBase64End2 = "");
private:
// encode table(编码表)
const static CString _base64_encode_chars;
// decode table(解码表)
const static char _base64_decode_chars[128];
};
//////////////////////////////////////////////////////////////////////////
// 函数: DWORD CalcANSItoBase64Len()
// 功能: 计算ANSI字符串转成Base64字符串需要多少内存
// 参数: dwANSILen ANSI字符串的长度
// 返回值: DWORD Base64字符串的长度
// 日期: [6/23/2005]
//////////////////////////////////////////////////////////////////////////
inline DWORD Base64::CalcANSItoBase64Len(DWORD dwANSILen)
{
return (dwANSILen%3) ? (dwANSILen+3)/3*4 : dwANSILen/3*4;
}
//////////////////////////////////////////////////////////////////////////
// 函数: DWORD CalcBase64toANSILen()
// 功能: 计算Base64字符串转成ANSI字符串需要多少内存
// 参数: dwANSILen Base64字符串的长度
// strBase64End2 Base64字符串结尾的二个字符串
// 返回值: DWORD ANSI字符串的长度
// 日期: [6/23/2005]
//////////////////////////////////////////////////////////////////////////
inline DWORD Base64::CalcBase64toANSILen(DWORD dwBase64Len, const CString strBase64End2)
{
//计算'='出现的次数,
int count = 0;
for (int i=0; i<strBase64End2.GetLength(); i++)
if (strBase64End2[i] == '=')
count ++;
DWORD dwANSILen = (dwBase64Len%4) ? (dwBase64Len+4)/4*3 : dwBase64Len/4*3;
dwANSILen -= count;
return dwANSILen;
}
//////////////////////////////////////////////////////////////////////////
// 函数: PSTR AllocMemBase64()
// 功能: 分配Base64字符串所需要的空间,这个内存需要用户手动删除
// 参数: dwANSILen ANSI字符串的长度
// 返回值: PSTR Base64内存地址
// 日期: [6/23/2005]
//////////////////////////////////////////////////////////////////////////
inline PSTR Base64::AllocMemBase64(DWORD dwANSILen)
{
int len = Base64::CalcANSItoBase64Len(dwANSILen);
char* pBase64 = new char[len+1];
ZeroMemory(pBase64, len+1);
return pBase64;
}
//////////////////////////////////////////////////////////////////////////
// 函数: PSTR AllocMemANSI()
// 功能: 分配Base64字符串所需要的空间,这个内存需要用户手动删除
// 参数: dwANSILen ANSI字符串的长度
// 返回值: PSTR Base64内存地址
// 日期: [6/23/2005]
//////////////////////////////////////////////////////////////////////////
inline PSTR Base64::AllocMemANSI(DWORD dwBase64Len)
{
int len = Base64::CalcBase64toANSILen(dwBase64Len);
char* pANSI = new char[len+1];
ZeroMemory(pANSI, len+1);
return pANSI;
}
//////////////////////////////////////////////////////////////////////////
// 函数: void FreeMemBase64()
// 功能: 删除用AllocMemBase64分配的内存
// 参数: pBase64 分配内在的地址
// 返回值: void
// 日期: [6/25/2005]
//////////////////////////////////////////////////////////////////////////
inline void Base64::FreeMemBase64(PSTR pBase64)
{
ASSERT(pBase64);
delete[] pBase64;
}
//////////////////////////////////////////////////////////////////////////
// 函数: void FreeMemANSI()
// 功能: 删除用AllocMemANSI分配的内存
// 参数: pANSI 分配内在的地址
// 返回值: void
// 日期: [6/25/2005]
//////////////////////////////////////////////////////////////////////////
inline void Base64::FreeMemANSI(PSTR pANSI)
{
ASSERT(pANSI);
delete[] pANSI;
}
#endif // !defined(AFX_BASE64_H__D1CE45BE_2DDD_47A2_9777_CA3BA8A42AE4__INCLUDED_)
// Base64.cpp: implementation of the Base64 class.
//
// 作者:王军建
//
// 用途:Base64的编码与解码
//
// 创建日期:2004-06-08
// 修改日期:2005-06-23
//////////////////////////////////////////////////////////////////////
#include "Base64.h"
#include <windows.h>
// 用于编码的字符
const CString Base64::_base64_encode_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// 用于解码的字符
const char Base64::_base64_decode_chars[] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
};
//////////////////////////////////////////////////////////////////////////
// 函数: CString encode()
// 功能: 将ANSI字符串转成Base64字符串
// 参数: in_str ANSI字符串
// 返回值: CString Base64字符串
// 日期: [6/23/2005]
//////////////////////////////////////////////////////////////////////////
CString Base64::encode(const CString in_str)
{
CString out_str;
unsigned char c1, c2, c3;
int i = 0;
int len = in_str.GetLength();
while ( i<len )
{
// read the first byte
c1 = in_str[i++];
if ( i==len ) // pad with "="
{
out_str += _base64_encode_chars[ c1>>2 ];
out_str += _base64_encode_chars[ (c1&0x3)<<4 ];
out_str += "==";
break;
}
// read the second byte
c2 = in_str[i++];
if ( i==len ) // pad with "="
{
out_str += _base64_encode_chars[ c1>>2 ];
out_str += _base64_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ];
out_str += _base64_encode_chars[ (c2&0xF)<<2 ];
out_str += "=";
break;
}
// read the third byte
c3 = in_str[i++];
// convert into four bytes string
out_str += _base64_encode_chars[ c1>>2 ];
out_str += _base64_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ];
out_str += _base64_encode_chars[ ((c2&0xF)<<2) | ((c3&0xC0)>>6) ];
out_str += _base64_encode_chars[ c3&0x3F ];
}
return out_str;
}
//////////////////////////////////////////////////////////////////////////
// 函数: CString decode()
// 功能: 将Base64字符串转成ANSI字符串
// 参数: in_str Base64字符串
// 返回值: CString ANSI字符串
// 日期: [6/23/2005]
//////////////////////////////////////////////////////////////////////////
CString Base64::decode(const CString in_str)
{
CString out_str;
char c1, c2, c3, c4;
int i = 0;
int len = in_str.GetLength();
while ( i<len)
{
// read the first byte
do {
c1 = _base64_decode_chars[ in_str[i++] ];
} while ( i<len && c1==-1);
if ( c1==-1)
break;
// read the second byte
do {
c2 = _base64_decode_chars[ in_str[i++] ];
} while ( i<len && c2==-1);
if ( c2==-1 )
break;
// assamble the first byte
out_str += char( (c1<<2) | ((c2&0x30)>>4) );
// read the third byte
do {
c3 = in_str[i++];
if ( c3==61 ) // meet with "=", break
return out_str;
c3 = _base64_decode_chars[ c3 ];
} while ( i<len && c3==-1);
if ( c3==-1 )
break;
// assamble the second byte
out_str += char( ((c2&0XF)<<4) | ((c3&0x3C)>>2) );
// read the fourth byte
do {
c4 = in_str[i++];
if ( c4==61 ) // meet with "=", break
return out_str;
c4 = _base64_decode_chars[ c4 ];
} while ( i<len && c4==-1 );
if ( c4==-1 )
break;
// assamble the third byte
out_str += char( ((c3&0x03)<<6) | c4 );
}
return out_str;
}
//////////////////////////////////////////////////////////////////////////
// 函数: void encode()
// 功能: 将ANSI字符串转成Base64字符串
// 参数: pIn ANSI字符串
// dwInLen ANSI字符串的长度
// pOut 放Base64字符串的内存
// pdwOutLen Base64字符串的长度
// 返回值: void
// 日期: [6/24/2005]
//////////////////////////////////////////////////////////////////////////
void Base64::encode(LPSTR pIn, DWORD dwInLen, LPSTR pOut, LPDWORD pdwOutLen)
{
unsigned char c1, c2, c3;
int i = 0, n = 0;
int len = dwInLen;
while ( i<len )
{
// read the first byte
c1 = pIn[i++];
if ( i==len ) // pad with "="
{
pOut[n++] = _base64_encode_chars[ c1>>2 ];
pOut[n++] = _base64_encode_chars[ (c1&0x3)<<4 ];
pOut[n++] = '=';
pOut[n++] = '=';
break;
}
// read the second byte
c2 = pIn[i++];
if ( i==len ) // pad with "="
{
pOut[n++] = _base64_encode_chars[ c1>>2 ];
pOut[n++] = _base64_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ];
pOut[n++] = _base64_encode_chars[ (c2&0xF)<<2 ];
pOut[n++] = '=';
break;
}
// read the third byte
c3 = pIn[i++];
// convert into four bytes string
pOut[n++] = _base64_encode_chars[ c1>>2 ];
pOut[n++] = _base64_encode_chars[ ((c1&0x3)<<4) | ((c2&0xF0)>>4) ];
pOut[n++] = _base64_encode_chars[ ((c2&0xF)<<2) | ((c3&0xC0)>>6) ];
pOut[n++] = _base64_encode_chars[ c3&0x3F ];
}
*pdwOutLen = n;
}
//////////////////////////////////////////////////////////////////////////
// 函数: void decode()
// 功能: 将Base64字符串转成ANSI字符串
// 参数: pIn Base64字符串
// dwInLen Base64字符串的长度
// pOut 放ANSI字符串的内存
// pdwOutLen ANSI字符串的长度
// 返回值: void
// 日期: [6/24/2005]
//////////////////////////////////////////////////////////////////////////
void Base64::decode(LPSTR pIn, DWORD dwInLen, LPSTR pOut, LPDWORD pdwOutLen)
{
char c1, c2, c3, c4;
int i = 0, n = 0;
int len = dwInLen;
while ( i<len)
{
// read the first byte
do {
c1 = _base64_decode_chars[ pIn[i++] ];
} while ( i<len && c1==-1);
if ( c1==-1)
break;
// read the second byte
do {
c2 = _base64_decode_chars[ pIn[i++] ];
} while ( i<len && c2==-1);
if ( c2==-1 )
break;
// assamble the first byte
pOut[n++] = char( (c1<<2) | ((c2&0x30)>>4) );
// read the third byte
do {
c3 = pIn[i++];
if ( c3==61 ) // meet with "=", break
goto end; //return;
c3 = _base64_decode_chars[ c3 ];
} while ( i<len && c3==-1);
if ( c3==-1 )
break;
// assamble the second byte
pOut[n++] = char( ((c2&0XF)<<4) | ((c3&0x3C)>>2) );
// read the fourth byte
do {
c4 = pIn[i++];
if ( c4==61 ) // meet with "=", break
goto end; //return;
c4 = _base64_decode_chars[ c4 ];
} while ( i<len && c4==-1 );
if ( c4==-1 )
break;
// assamble the third byte
pOut[n++] = char( ((c3&0x03)<<6) | c4 );
}
end:
*pdwOutLen = n;
}
//////////////////////////////////////////////////////////////////////////
// 函数: BOOL encodeMemMap()
// 功能: 将ANSI格式文件转成Base64格式文件
// 参数: fIn ANSI格式的文件名
// fOut Base64格式的文件名
// 返回值: BOOL TRUE(成功) FALSE(失败)
// 日期: [6/24/2005]
//////////////////////////////////////////////////////////////////////////
BOOL Base64::encodeMemMap(LPCTSTR fIn, LPCTSTR fOut)
{
HANDLE hIn, hOut, hInMap, hOutMap;
LPSTR pIn, pInFile;
LPSTR pOut, pOutFile;
DWORD dwInLow, dwOutLow;
DWORD dwOutLen = 0;
hIn = CreateFile(fIn, GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
hInMap = CreateFileMapping(hIn, NULL, PAGE_READONLY,
0, 0, NULL);
pInFile = (LPSTR)MapViewOfFile(hInMap, FILE_MAP_READ, 0, 0, 0);
hOut = CreateFile(fOut, GENERIC_READ|GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
dwInLow = GetFileSize(hIn, NULL);
dwOutLow = CalcANSItoBase64Len(dwInLow);
hOutMap = CreateFileMapping(hOut, NULL, PAGE_READWRITE,
0, dwOutLow, NULL);
pOutFile = (LPSTR)MapViewOfFile(hOutMap, FILE_MAP_WRITE, 0, 0, dwOutLow);
//转换
pIn = pInFile;
pOut = pOutFile;
encode(pIn, dwInLow, pOut, &dwOutLen);
UnmapViewOfFile(pOutFile); UnmapViewOfFile(pInFile);
CloseHandle(hOutMap); CloseHandle(hInMap);
CloseHandle(hOut); CloseHandle(hIn);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// 函数: BOOL decodeMemMap()
// 功能: 将Base64格式文件转成ANSI格式文件
// 参数: fIn Base64格式的文件名
// fOut ANSI格式的文件名
// 返回值: BOOL TRUE(成功) FALSE(失败)
// 日期: [6/24/2005]
//////////////////////////////////////////////////////////////////////////
BOOL Base64::decodeMemMap(LPCTSTR fIn, LPCTSTR fOut)
{
HANDLE hIn, hOut, hInMap, hOutMap;
LPSTR pIn, pInFile;
LPSTR pOut, pOutFile;
DWORD dwInLow, dwOutLow;
DWORD dwOutLen = 0;
TCHAR szBuf[3] = "";
hIn = CreateFile(fIn, GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
dwInLow = GetFileSize(hIn, NULL);
if (dwInLow >= 2)
{
SetFilePointer(hIn, -2, NULL, FILE_END);
DWORD result;
ReadFile(hIn, szBuf, 2, &result, NULL);
dwOutLow = CalcBase64toANSILen(dwInLow, szBuf);
}
hInMap = CreateFileMapping(hIn, NULL, PAGE_READONLY,
0, 0, NULL);
pInFile = (LPSTR)MapViewOfFile(hInMap, FILE_MAP_READ, 0, 0, 0);
hOut = CreateFile(fOut, GENERIC_READ|GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
hOutMap = CreateFileMapping(hOut, NULL, PAGE_READWRITE,
0, dwOutLow, NULL);
pOutFile = (LPSTR)MapViewOfFile(hOutMap, FILE_MAP_WRITE, 0, 0, dwOutLow);
//转换
pIn = pInFile;
pOut = pOutFile;
decode(pIn, dwInLow, pOut, &dwOutLen);
UnmapViewOfFile(pOutFile); UnmapViewOfFile(pInFile);
CloseHandle(hOutMap); CloseHandle(hInMap);
CloseHandle(hOut); CloseHandle(hIn);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// 函数: BOOL encode()
// 功能: 将ANSI格式文件转成Base64格式文件
// 参数: cstrSrc ANSI格式的文件名
// cstrDes Base64格式的文件名
// 返回值: BOOL TRUE(成功) FALSE(失败)
// 日期: [6/24/2005]
//////////////////////////////////////////////////////////////////////////
BOOL Base64::encode(const CString cstrSrc, const CString cstrDes)
{
try
{
CFile file(cstrSrc, CFile::modeRead);
CFile desFile(cstrDes, CFile::modeWrite | CFile::modeCreate);
int length = file.GetLength();
while (length>0)
{
int size = 4095; //必须是3的倍数,不然就被'='所烦。解码只要以四的倍数即可
PSTR buffer=NULL;
buffer = new TCHAR[size];
UINT nBytesRead = file.Read(buffer, size);
// 将Base64格式写入文件
PSTR pszBase64 = AllocMemBase64(nBytesRead);
DWORD dwBase64 = 0;
encode(buffer, nBytesRead, pszBase64, &dwBase64);
desFile.Write(pszBase64, dwBase64);
FreeMemBase64(pszBase64);
delete[] buffer;
length -= nBytesRead;
}
}
catch(CFileException *e)
{
// MessageBox(NULL, e->ReportError(), "error", MB_OK);
e->Delete();
return FALSE;
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
// 函数: BOOL decode()
// 功能: 将Base64格式文件转成ANSI格式文件
// 参数: cstrSrc Base64格式的文件名
// cstrDes ANSI格式的文件名
// 返回值: BOOL TRUE(成功) FALSE(失败)
// 日期: [6/24/2005]
//////////////////////////////////////////////////////////////////////////
BOOL Base64::decode(const CString cstrSrc, const CString cstrDes)
{
try
{
CFile file(cstrSrc, CFile::modeRead);
CFile desFile(cstrDes, CFile::modeWrite | CFile::modeCreate);
// 读取ANSI文件放入cstrANSI
int length = file.GetLength();
while (length>0)
{
int size = 4096; //必须是4的倍数
PSTR buffer=NULL;
buffer = new TCHAR[size];
UINT nBytesRead = file.Read(buffer, size);
PSTR pszANSI = AllocMemANSI(nBytesRead);
DWORD dwANSI = 0;
decode(buffer, nBytesRead, pszANSI, &dwANSI);
desFile.Write(pszANSI, dwANSI);
FreeMemANSI(pszANSI);
delete[] buffer;
length -= nBytesRead;
}
}
catch(CFileException *e)
{
// MessageBox(NULL, e->ReportError(), "error", MB_OK);
e->Delete();
return FALSE;
}
return TRUE;
}