我的Base64编码类,实际使用中

来源:互联网 发布:网络推广专员策划 编辑:程序博客网 时间:2024/04/27 17:46

头文件

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

#if !defined(AFX_BASE64_H__8FF94494_89EB_4F4D_A8B4_B97BC7A14062__INCLUDED_)
#define AFX_BASE64_H__8FF94494_89EB_4F4D_A8B4_B97BC7A14062__INCLUDED_

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

class CBase64 
{
public:
 int Decode(LPCTSTR szDecoding, char *szOutput);
 //CString Encode(LPBYTE szEncoding, int nSize);
 //CString Decode(LPCTSTR lpszSrc);
 CString Encode(LPCTSTR lpszSrc, int nSize);
 CBase64();
 virtual ~CBase64();
private:
 void write_bits(UINT nBits, int nNumBits, char *szOutput, int& i);
 UINT read_bits(int nNumBits, int * pBitsRead, int& lp);
 BYTE *m_szInput;
 long m_lszInput;
 CString m_sBase64Alphabet;
 int m_nMask[9];
 int m_nBitsRemaining;
 int m_nInputSize;
 long m_lBitStorage;
};

#endif // !defined(AFX_BASE64_H__8FF94494_89EB_4F4D_A8B4_B97BC7A14062__INCLUDED_)

cpp文件

 

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

#include "stdafx.h"
//#include "TestBackUp.h"
#include "Base64.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBase64::CBase64()
{
 m_sBase64Alphabet =_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");

 m_nMask[0]=0;
 m_nMask[1]=1;
 m_nMask[2]=3;
 m_nMask[3]=7;
 m_nMask[4]=15;
 m_nMask[5]=31;
 m_nMask[6]=63;
 m_nMask[7]=127;
 m_nMask[8]=255;
 m_nBitsRemaining=0;
 m_nInputSize=0;
 m_lszInput=0;
 m_szInput=0;
}

CBase64::~CBase64()
{

}

//CString CBase64::Encode(LPBYTE szEncoding, int nSize)
CString CBase64::Encode(LPCTSTR lpszSrc, 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 ];
  nDigit = read_bits( nNumBits, &nNumBits, lp );
 }
 // Pad with '=' as per RFC 1521
 while( sOutput.GetLength() % 4 != 0 )
 {
  sOutput += '=';
 }
 return sOutput;*/

 const char BASE64_ENCODE_TABLE[64] = {
 65,  66,  67,  68,  69,  70,  71,  72,  // 00 - 07
 73,  74,  75,  76,  77,  78,  79,  80,  // 08 - 15
 81,  82,  83,  84,  85,  86,  87,  88,  // 16 - 23
 89,  90,  97,  98,  99, 100, 101, 102,  // 24 - 31
 103, 104, 105, 106, 107, 108, 109, 110,  // 32 - 39
 111, 112, 113, 114, 115, 116, 117, 118,  // 40 - 47
 119, 120, 121, 122,  48,  49,  50,  51,  // 48 - 55
 52,  53,  54,  55,  56,  57,  43,  47 };// 56 - 63

 unsigned int iTest;

 LPCTSTR pInBuffer = lpszSrc;

 //int nSize = (int)_tcslen(lpszSrc);
 char* pOutBuffer=new char[nSize/3*4+5];
 ZeroMemory(pOutBuffer,nSize/3*4+5);

 for(UINT i=0; i< nSize / 3;i++) //_tcslen(lpszSrc)
 {
  iTest = (unsigned char) *pInBuffer++;
  iTest = iTest << 8;

  iTest = iTest | (unsigned char) *pInBuffer++;
  iTest = iTest << 8;

  iTest = iTest | (unsigned char) *pInBuffer++;

  //以4 byte倒序写入输出缓冲
  pOutBuffer[3] = BASE64_ENCODE_TABLE[iTest & 0x3F];
  iTest = iTest >> 6;
  pOutBuffer[2] = BASE64_ENCODE_TABLE[iTest & 0x3F];
  iTest = iTest >> 6;
  pOutBuffer[1] = BASE64_ENCODE_TABLE[iTest & 0x3F];
  iTest = iTest >> 6;
  pOutBuffer[0] = BASE64_ENCODE_TABLE[iTest];
  pOutBuffer+=4;
 }

 //设置尾部
 switch (nSize % 3) //_tcslen(lpszSrc)
 {
  case 0:
  break;
  case 1:
  iTest = (unsigned char) *pInBuffer;
  iTest = iTest << 4;
  pOutBuffer[1] = BASE64_ENCODE_TABLE[iTest & 0x3F];
  iTest = iTest >> 6;
  pOutBuffer[0] = BASE64_ENCODE_TABLE[iTest];
  pOutBuffer[2] = '='; //用'='也就是64码填充剩余部分
  pOutBuffer[3] = '=';
  break;
  case 2:
  iTest = (unsigned char) *pInBuffer++;
  iTest = iTest << 8;
  iTest = iTest | (unsigned char) *pInBuffer;
  iTest = iTest << 2;
  pOutBuffer[2] = BASE64_ENCODE_TABLE[iTest & 0x3F];
  iTest = iTest >> 6;
  pOutBuffer[1] = BASE64_ENCODE_TABLE[iTest & 0x3F];
  iTest = iTest >> 6;
  pOutBuffer[0] = BASE64_ENCODE_TABLE[iTest];
  pOutBuffer[3] = '='; // Fill remaining byte.
  break;
 }
 pOutBuffer-=nSize/3*4;
 CString strEncode = pOutBuffer;
 delete [] pOutBuffer;
 pOutBuffer=NULL;
 return strEncode;

}

// 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.LPCTSTR LPTSTR
int CBase64::Decode(LPCTSTR szDecoding, char *szOutput)
//CString CBase64::Decode(LPCTSTR lpszSrc)
{
 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 0;
  }
  else if( nDigit >= 0 )
   // i (index into output) is incremented by write_bits()
   write_bits( nDigit & 0x3F, 6, szOutput, i );
 }
 return i;

/* ASSERT(lpszSrc != NULL && AfxIsValidString(lpszSrc));
 const unsigned int BASE64_DECODE_TABLE[256] = {
 255, 255, 255, 255, 255, 255, 255, 255, //  00 -  07
 255, 255, 255, 255, 255, 255, 255, 255, //  08 -  15
 255, 255, 255, 255, 255, 255, 255, 255, //  16 -  23
 255, 255, 255, 255, 255, 255, 255, 255, //  24 -  31
 255, 255, 255, 255, 255, 255, 255, 255, //  32 -  39
 255, 255, 255,  62, 255, 255, 255,  63, //  40 -  47
 52,  53,  54,  55,  56,  57,  58,  59, //  48 -  55
 60,  61, 255, 255, 255, 255, 255, 255, //  56 -  63
 255,   0,   1,   2,   3,   4,   5,   6, //  64 -  71
 7,   8,   9,  10,  11,  12,  13,  14, //  72 -  79
 15,  16,  17,  18,  19,  20,  21,  22, //  80 -  87
 23,  24,  25, 255, 255, 255, 255, 255, //  88 -  95
 255,  26,  27,  28,  29,  30,  31,  32, //  96 - 103
 33,  34,  35,  36,  37,  38,  39,  40, // 104 - 111
 41,  42,  43,  44,  45,  46,  47,  48, // 112 - 119
 49,  50,  51, 255, 255, 255, 255, 255, // 120 - 127
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255,
 255, 255, 255, 255, 255, 255, 255, 255 };


 const int nSrcCount=(int)_tcslen(lpszSrc);
 int nSize=nSrcCount/4*3;
 if(lpszSrc[nSrcCount-1]=='=')
  nSize--;
 if(lpszSrc[nSrcCount-2]=='=')
  nSize--;
 char* pOutBuffer=new char[nSize+3];
 ZeroMemory(pOutBuffer,nSize+3);
 LPCTSTR pInBuffer=lpszSrc;
 UINT iTest,iPack;
 for(int i=0;i<nSize/3 ;i++)
 {
  for(int j=0;j<4;j++)
  {
   iTest = BASE64_DECODE_TABLE[*pInBuffer++]; // Read from InputBuffer.
   //InPtr++;
   if (iTest == 0xFF)
   {
    j--;
    continue; //读到255非法字符
   }
   iPack = iPack << 6 ;
   iPack = iPack | iTest ;
  }
  pOutBuffer[2] = iPack;
  iPack = iPack >> 8;
  pOutBuffer[1] = iPack;
  iPack = iPack >> 8;
  pOutBuffer[0] = iPack;
  //准备写入后3位
  pOutBuffer+= 3; iPack = 0;

 }
 switch(nSize%3)
 {
  case 1:
   iTest = BASE64_DECODE_TABLE[*pInBuffer++]; // Read from InputBuffer.
   if (iTest != 0xFF)
   {
    iPack = iPack << 6 ;
    iPack = iPack | iTest ;
   }
   iTest = BASE64_DECODE_TABLE[*pInBuffer++]; // Read from InputBuffer.
   if (iTest != 0xFF)
   {
    iPack = iPack << 6 ;
    iPack = iPack | iTest ;
   }
   iPack = iPack >> 4;
   pOutBuffer[0] = iPack;
   pOutBuffer++;
  break;
  case 2:
   iTest = BASE64_DECODE_TABLE[*pInBuffer++]; // Read from InputBuffer.
   if (iTest != 0xFF)
   {
    iPack = iPack << 6 ;
    iPack = iPack | iTest ;
   }
   iTest = BASE64_DECODE_TABLE[*pInBuffer++]; // Read from InputBuffer.
   if (iTest != 0xFF)
   {
    iPack = iPack << 6 ;
    iPack = iPack | iTest ;
   }
   iTest = BASE64_DECODE_TABLE[*pInBuffer++]; // Read from InputBuffer.
   if (iTest != 0xFF)
   {
    iPack = iPack << 6 ;
    iPack = iPack | iTest ;
   }
   iPack = iPack >> 2;
   pOutBuffer[1] = iPack;
   iPack = iPack >> 8;
   pOutBuffer[0] = iPack;
   pOutBuffer+=2;
  break;
  default:
  break;
 }
 pOutBuffer-=nSize;
 CString strDecode = pOutBuffer;
 delete pOutBuffer;
 return strDecode;*/

}

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, char *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;
 }
}

原创粉丝点击