base64编码函数

来源:互联网 发布:笔记本mac地址修改器 编辑:程序博客网 时间:2024/04/30 12:04

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:
};

实现:

// Base64.cpp: implementation of the CBase64 class.
// Author: Wes Clyburn (clyburnw@enmu.edu)
//
// This code was practically stolen from:
// Dr. Dobb's Journal, September 1995,
// "Mime and Internet Mail", by Tim Kientzle
//////////////////////////////////////////////////////////////////////

#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()
{
}

CBase64::~CBase64()
{
}

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];
  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 0;
  }
  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;
 }
}

原创粉丝点击