Base64编码解码类

// Base64.h: interface for the CBase64 class.
/**///

#if !defined(AFX_BASE64_H__FD6A25D1_EE0E_11D1_870E_444553540001__INCLUDED_)
#define AFX_BASE64_H__FD6A25D1_EE0E_11D1_870E_444553540001__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "MIMECode.h"

// CBase64
// An encoding agent that handles Base64
//
class CBase64 : public CMIMECode
...{
public:
    CBase64();
    virtual ~CBase64();

// Override the base class mandatory functions
    virtual int Decode( LPCTSTR szDecoding, LPTSTR szOutput );
    virtual CString Encode( LPCTSTR szEncoding, int nSize );

protected:
    void write_bits( UINT nBits, int nNumBts, LPTSTR szOutput, int& lp );
    UINT read_bits( int nNumBits, int* pBitsRead, int& lp );

    int m_nInputSize;
    int m_nBitsRemaining;
    ULONG m_lBitStorage;
    LPCTSTR m_szInput;

    static int m_nMask[];
    static CString m_sBase64Alphabet;
private:
};

CString Base64String(CString str,CString Charset = "gb2312" );

#endif // !defined(AFX_BASE64_H__FD6A25D1_EE0E_11D1_870E_444553540001__INCLUDED_)






// Base64.cpp: implementation of the CBase64 class.
//

#include "stdafx.h"
#include "Base64.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// Static Member Initializers
//

// The 7-bit alphabet used to encode binary information
CString CBase64::m_sBase64Alphabet =
_T( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );

int CBase64::m_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };

//
// Construction/Destruction
//

CBase64::CBase64()
{

     m_nInputSize=0;
     m_nBitsRemaining=0;
     m_lBitStorage=0;
}

CBase64::~CBase64()
{
}

CString Base64String(CString str, CString Charset)
{
    //"“From: =?gb2312?B?us7TsQ==?= <hy@ipiinfo.com>”"
    CBase64 code;
    CString strok=code.Encode(str,str.GetLength());
    CString rt;
    rt.Format("=?%s?B?%s==?=",Charset,strok);
  
    return rt;

}


CString CBase64::Encode(LPCTSTR szEncoding, int nSize)
{
    CString sOutput = _T( "" );
    int nNumBits = 6;
    UINT nDigit;
    int lp = 0;

    ASSERT( szEncoding != NULL );
    if( szEncoding == NULL )
        return sOutput;
    m_szInput = szEncoding;
    m_nInputSize = nSize;

    m_nBitsRemaining = 0;
    nDigit = read_bits( nNumBits, &nNumBits, lp );
    while( nNumBits > 0 )
    {
        sOutput += m_sBase64Alphabet[ (int)nDigit ];
        if((sOutput.GetLength()-76) % 78 == 0)
            sOutput+=" ";
        nDigit = read_bits( nNumBits, &nNumBits, lp );
    }
    // Pad with '=' as per RFC 1521
    while( sOutput.GetLength() % 4 != 0 )
    {
        sOutput += '=';
    }
    return sOutput;
}

// The size of the output buffer must not be less than
// 3/4 the size of the input buffer. For simplicity,
// make them the same size.
int CBase64::Decode(LPCTSTR szDecoding, LPTSTR szOutput)
{
    CString sInput;
    int c, lp =0;
    int nDigit;
    int nDecode[ 256 ];

    ASSERT( szDecoding != NULL );
    ASSERT( szOutput != NULL );
    if( szOutput == NULL )
        return 0;
    if( szDecoding == NULL )
        return 0;
    sInput = szDecoding;
    if( sInput.GetLength() == 0 )
        return 0;

    // Build Decode Table
    //
    for( int i = 0; i < 256; i++ )
        nDecode[i] = -2; // Illegal digit
  
    for( i=0; i < 64; i++ )
    {
        nDecode[ m_sBase64Alphabet[ i ] ] = i;
        nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit
        nDecode[ '=' ] = -1;
        nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char
    }

    // Clear the output buffer
    memset( szOutput, 0, sInput.GetLength() + 1 );

    // Decode the Input
    //
    for( lp = 0, i = 0; lp < sInput.GetLength(); lp++ )
    {
        c = sInput[ lp ];
        nDigit = nDecode[ c & 0x7F ];
        if( nDigit < -1 )
        {
            return i;
        }
        else if( nDigit >= 0 )
            // i (index into output) is incremented by write_bits()
            write_bits( nDigit & 0x3F, 6, szOutput, i );
    }  
    return i;
}




UINT CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)
{
    ULONG lScratch;
    while( ( m_nBitsRemaining < nNumBits ) &&
           ( lp < m_nInputSize ) )
    {
        int c = m_szInput[ lp++ ];
        m_lBitStorage <<= 8;
        m_lBitStorage |= (c & 0xff);
        m_nBitsRemaining += 8;
    }
    if( m_nBitsRemaining < nNumBits )
    {
        lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );
        *pBitsRead = m_nBitsRemaining;
        m_nBitsRemaining = 0;
    }
    else
    {
        lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );
        *pBitsRead = nNumBits;
        m_nBitsRemaining -= nNumBits;
    }
    return (UINT)lScratch & m_nMask[nNumBits];
}


void CBase64::write_bits(UINT nBits,
                         int nNumBits,
                         LPTSTR szOutput,
                         int& i)
{
    UINT nScratch;

    m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;
    m_nBitsRemaining += nNumBits;
    while( m_nBitsRemaining > 7 )
    {
        nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);
        szOutput[ i++ ] = nScratch & 0xFF;
        m_nBitsRemaining -= 8;
    }

 

(原创)昨天为了测试我的终端,自己写了个模拟服务器,用到BASE64 编解码,已用了GoAhead的代码,发现不支持中文,自己改造一下,解决了问题。现在把代码发上来给大家借鉴。


/*
* base64.c -- Base64 Mime encoding
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*
* $Id: base64.c,v 1.1 2005/08/12 06:50:14 archfree Exp $
*/

/******************************** Description *********************************/

/*
* The base64 command encodes and decodes a string in mime base64 format
*/


/******************************** Local Data **********************************/
/*
* Mapping of ANSI chars to base64 Mime encoding alphabet (see below)
*/

#if 0
static char map64[] = {
-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,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
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,
-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, -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, -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, -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, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
#endif
static char map64[] = {
-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, 0, -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, -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, -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, -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};

static char alphabet64[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
};

/*********************************** Code *************************************/
/*
* Decode a buffer from "string" and into "outbuf"
*/

int websDecode64(char *outbuf, char *string, int outlen)
{
unsigned long shiftbuf;
char *cp, *op;
int c, i, j, shift;

op = outbuf;
*op = '/0';
cp = string;
while (*cp && *cp != '=') {
/*
* Map 4 (6bit) input bytes and store in a single long (shiftbuf)
*/
shiftbuf = 0;
shift = 18;
for (i = 0; i < 4 && *cp && *cp != '='; i++, cp++) {
c = map64[*cp & 0xff];
if (c == -1) {
#if zwhtemp
error(E_L, E_LOG, T("Bad string: %s at %c index %d"), string,
c, i);
#endif
return -1;
}
shiftbuf = shiftbuf | (c << shift);
shift -= 6;
}
/*
* Interpret as 3 normal 8 bit bytes (fill in reverse order).
* Check for potential buffer overflow before filling.
*/
--i;
if ((op + i) >= &outbuf[outlen]) {
//gstrcpy(outbuf, T("String too big"));]
//strcpy(outbuf, T("String too big"));
strcpy(outbuf, "String too big");

return -1;
}
for (j = 0; j < i; j++) {
*op++ = (char) ((shiftbuf >> (8 * (2 - j))) & 0xff);
}
*op = '/0';
}
return 0;
}


/******************************************************************************/
/*
* Encode a buffer from "string" into "outbuf"
*/

void websEncode64(char *outbuf, char *string, int outlen)
{
unsigned long shiftbuf;
char *cp, *op;
int x, i, j, shift;

op = outbuf;
*op = '/0';
cp = string;
while (*cp) {
/*
* Take three characters and create a 24 bit number in shiftbuf
*/
shiftbuf = 0;
for (j = 2; j >= 0 && *cp; j--, cp++) {
shiftbuf |= ((*cp & 0xff) << (j * 8));
}
/*
* Now convert shiftbuf to 4 base64 letters. The i,j magic calculates
* how many letters need to be output.
*/
shift = 18;
for (i = ++j; i < 4 && op < &outbuf[outlen] ; i++) {
x = (shiftbuf >> shift) & 0x3f;
*op++ = alphabet64[(shiftbuf >> shift) & 0x3f];
shift -= 6;
}
/*
* Pad at the end with '='
*/
while (j-- > 0) {
*op++ = '=';
}
*op = '/0';
}
}


=============

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

//
#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;
}

-===================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值