算法系列8《Base64》

来源:互联网 发布:网络的利与弊 编辑:程序博客网 时间:2024/05/21 17:23

目录(?)[-]

  1. Base64索引表
  2. C实现代码
    1. Base64h
    2. CBase64cpp

        Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,Base64编码可用于在HTTP环境下传递较长的标识信息。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。金融数据也常以base64编码格式提供。



         Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。


Base64索引表





C++实现代码





1. 《Base64.h》

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. // Base64.h  
  2. #pragma once  
  3. #include <windows.h>  
  4.   
  5. class CBase64  
  6. {  
  7.     // Internal bucket class.  
  8.     class TempBucket  
  9.     {  
  10.     public:  
  11.         BYTE         nData[4];  
  12.         BYTE         nSize;  
  13.         void         Clear() { ::ZeroMemory(nData, 4); nSize = 0; };  
  14.     };  
  15.   
  16.     PBYTE                       m_pDBuffer;  
  17.     PBYTE                       m_pEBuffer;  
  18.     DWORD                       m_nDBufLen;  
  19.     DWORD                       m_nEBufLen;  
  20.     DWORD                       m_nDDataLen;  
  21.     DWORD                       m_nEDataLen;  
  22.   
  23. public:  
  24.     CBase64();  
  25.     virtual ~CBase64();  
  26.   
  27. public:  
  28.     virtual PBYTE         Encode(const PBYTEDWORD);  
  29.     virtual PBYTE      Decode(const PBYTEDWORD);  
  30.     virtual CString         Encode(LPCSTR sMessage);  
  31.     virtual CString      Decode(LPCSTR sMessage);  
  32.   
  33.     virtual LPCSTR     DecodedMessage() const;  
  34.     virtual LPCSTR     EncodedMessage() const;  
  35.   
  36.     virtual void         AlloCEncodeDlg(DWORD);  
  37.     virtual void         AllocDecode(DWORD);  
  38.     virtual void         SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen);  
  39.     virtual void         SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen);  
  40.   
  41. protected:  
  42.     virtual void         _EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);  
  43.     virtual ULONG         _DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);  
  44.     virtual void         _EncodeRaw(TempBucket &, const TempBucket &);  
  45.     virtual void         _DecodeRaw(TempBucket &, const TempBucket &);  
  46.     virtual BOOL         _IsBadMimeChar(BYTE);  
  47.   
  48.     static char         m_DecodeTable[256];  
  49.     static BOOL         m_Init;  
  50.     void                       _Init();  
  51. };  


2. 《CBase64.cpp》

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. // CBase64.cpp  
  2. // CBase64.cpp: implementation of the CBase64 class.  
  3.   
  4. //////////////////////////////////////////////////////////////////////  
  5. #include "stdAfx.h"  
  6. #include "Base64.h"  
  7. #include "DataX.h"  
  8.   
  9. using namespace DataX;  
  10.   
  11. // Digits...  
  12. static char Base64Digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  13.   
  14. BOOL CBase64::m_Init   = FALSE;  
  15. char CBase64::m_DecodeTable[256];  
  16.   
  17. #ifndef PAGESIZE  
  18. #define PAGESIZE       4096  
  19. #endif  
  20.   
  21. #ifndef ROUNDTOPAGE  
  22. #define ROUNDTOPAGE(a)     ((((a) / 4096)  +  1) * 4096)  
  23. #endif  
  24.   
  25. //////////////////////////////////////////////////////////////////////  
  26. // Construction/Destruction  
  27. //////////////////////////////////////////////////////////////////////  
  28.   
  29. CBase64::CBase64()  
  30.     : m_pDBuffer(NULL),  
  31.     m_pEBuffer(NULL),  
  32.     m_nDBufLen(0),  
  33.     m_nEBufLen(0)  
  34. {  
  35.   
  36. }  
  37.   
  38. CBase64::~CBase64()  
  39. {  
  40.     if (m_pDBuffer != NULL)  
  41.     {  
  42.         delete [] m_pDBuffer;  
  43.     }  
  44.   
  45.     if (m_pEBuffer != NULL)  
  46.     {  
  47.         delete [] m_pEBuffer;  
  48.     }  
  49. }  
  50.   
  51. LPCSTR CBase64::DecodedMessage() const  
  52. {  
  53.     return (LPCSTR) m_pDBuffer;  
  54. }  
  55.   
  56. LPCSTR CBase64::EncodedMessage() const  
  57. {  
  58.     return (LPCSTR) m_pEBuffer;  
  59. }  
  60.   
  61. void CBase64::AlloCEncodeDlg(DWORD nSize)  
  62. {  
  63.     if (m_nEBufLen < nSize)  
  64.     {  
  65.         if (m_pEBuffer != NULL)  
  66.             delete [] m_pEBuffer;  
  67.   
  68.         m_nEBufLen = ROUNDTOPAGE(nSize);  
  69.         m_pEBuffer = new BYTE[m_nEBufLen];  
  70.     }  
  71.   
  72.     ::ZeroMemory(m_pEBuffer, m_nEBufLen);  
  73.     m_nEDataLen = 0;  
  74. }  
  75.   
  76. void CBase64::AllocDecode(DWORD nSize)  
  77. {  
  78.     if (m_nDBufLen < nSize)  
  79.     {  
  80.         if (m_pDBuffer != NULL)  
  81.         {  
  82.             delete [] m_pDBuffer;  
  83.         }  
  84.   
  85.         m_nDBufLen = ROUNDTOPAGE(nSize);  
  86.         m_pDBuffer = new BYTE[m_nDBufLen];  
  87.     }  
  88.   
  89.     ::ZeroMemory(m_pDBuffer, m_nDBufLen);  
  90.     m_nDDataLen = 0;  
  91. }  
  92.   
  93. void CBase64::SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen)  
  94. {  
  95.     DWORD ii = 0;  
  96.   
  97.     AlloCEncodeDlg(nBufLen);  
  98.     while(ii < nBufLen)  
  99.     {  
  100.         if (!_IsBadMimeChar(pBuffer[ii]))  
  101.         {  
  102.             m_pEBuffer[m_nEDataLen] = pBuffer[ii];  
  103.             m_nEDataLen ++ ;  
  104.         }  
  105.   
  106.         ii ++ ;  
  107.     }  
  108. }  
  109.   
  110. void CBase64::SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen)  
  111. {  
  112.     AllocDecode(nBufLen);  
  113.     ::CopyMemory(m_pDBuffer, pBuffer, nBufLen);  
  114.     m_nDDataLen = nBufLen;  
  115. }  
  116.   
  117. PBYTE CBase64::Encode(const PBYTE pBuffer, DWORD nBufLen)  
  118. {  
  119.     SetDecodeBuffer(pBuffer, nBufLen);  
  120.     AlloCEncodeDlg(nBufLen * 2);  
  121.   
  122.     TempBucket     Raw;  
  123.     DWORD       nIndex = 0;  
  124.   
  125.     while((nIndex  +  3) <= nBufLen)  
  126.     {  
  127.         Raw.Clear();  
  128.         ::CopyMemory(&Raw, m_pDBuffer  +  nIndex, 3);  
  129.         Raw.nSize = 3;  
  130.         _EncodeToBuffer(Raw, m_pEBuffer  +  m_nEDataLen);  
  131.         nIndex += 3;  
  132.   
  133.         m_nEDataLen  += 4;  
  134.     }  
  135.   
  136.     if (nBufLen > nIndex)  
  137.     {  
  138.         Raw.Clear();  
  139.         Raw.nSize = (BYTE) (nBufLen - nIndex);  
  140.         ::CopyMemory(&Raw, m_pDBuffer  +  nIndex, nBufLen - nIndex);  
  141.         _EncodeToBuffer(Raw, m_pEBuffer  +  m_nEDataLen);  
  142.         m_nEDataLen  += 4;  
  143.     }  
  144.   
  145.     return m_pEBuffer;  
  146. }  
  147.   
  148. CString CBase64::Encode(LPCSTR szMessage)  
  149. {  
  150.     CString strHex = _T("");  
  151.     if (szMessage != NULL)  
  152.     {  
  153.         CBase64::Encode((const PBYTE)szMessage, lstrlenA(szMessage));  
  154.         if (m_nEDataLen > 0)  
  155.         {  
  156.             AscToHex(m_pEBuffer, m_nEDataLen, strHex);  
  157.         }  
  158.     }  
  159.   
  160.     return strHex;  
  161. }  
  162.   
  163. PBYTE CBase64::Decode(const PBYTE pBuffer, DWORD dwBufLen)  
  164. {  
  165.     if (!CBase64::m_Init)  
  166.         _Init();  
  167.   
  168.     SetEncodeBuffer(pBuffer, dwBufLen);  
  169.   
  170.     AllocDecode(dwBufLen);  
  171.   
  172.     TempBucket     Raw;  
  173.   
  174.     DWORD   nIndex = 0;  
  175.   
  176.     while((nIndex  +  4) <= m_nEDataLen)  
  177.     {  
  178.         Raw.Clear();  
  179.         Raw.nData[0] = CBase64::m_DecodeTable[m_pEBuffer[nIndex]];  
  180.         Raw.nData[1] = CBase64::m_DecodeTable[m_pEBuffer[nIndex  +  1]];  
  181.         Raw.nData[2] = CBase64::m_DecodeTable[m_pEBuffer[nIndex  +  2]];  
  182.   
  183.         Raw.nData[3] = CBase64::m_DecodeTable[m_pEBuffer[nIndex  +  3]];  
  184.   
  185.         if (Raw.nData[2] == 255)  
  186.             Raw.nData[2] = 0;  
  187.         if (Raw.nData[3] == 255)  
  188.             Raw.nData[3] = 0;  
  189.   
  190.         Raw.nSize = 4;  
  191.         _DecodeToBuffer(Raw, m_pDBuffer  +  m_nDDataLen);  
  192.         nIndex  += 4;  
  193.         m_nDDataLen  += 3;  
  194.     }  
  195.   
  196.     // If nIndex < m_nEDataLen, then we got a decode message without padding.  
  197.     // We may want to throw some kind of warning here, but we are still required  
  198.     // to handle the decoding as if it was properly padded.  
  199.     if (nIndex < m_nEDataLen)  
  200.     {  
  201.         Raw.Clear();  
  202.         for(DWORD ii = nIndex; ii < m_nEDataLen; ii ++ )  
  203.         {  
  204.             Raw.nData[ii - nIndex] = CBase64::m_DecodeTable[m_pEBuffer[ii]];  
  205.             Raw.nSize ++ ;  
  206.             if (Raw.nData[ii - nIndex] == 255)  
  207.                 Raw.nData[ii - nIndex] = 0;  
  208.         }  
  209.   
  210.         _DecodeToBuffer(Raw, m_pDBuffer  +  m_nDDataLen);  
  211.         m_nDDataLen  += (m_nEDataLen - nIndex);  
  212.     }  
  213.   
  214.     return m_pDBuffer;  
  215. }  
  216.   
  217.   
  218. CString CBase64::Decode(LPCSTR pszMessage)  
  219. {  
  220.     if (!pszMessage)  
  221.     {  
  222.         return _T("");  
  223.     }  
  224.   
  225.     CBase64::Decode((const PBYTE)pszMessage, lstrlenA(pszMessage));  
  226.     CString strHex = _T("");  
  227.     if (m_nDDataLen > 0)  
  228.     {  
  229.         AscToHex(m_pDBuffer, m_nDDataLen, strHex);  
  230.     }  
  231.   
  232.     return strHex;  
  233.   
  234. }  
  235.   
  236. DWORD CBase64::_DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)  
  237. {  
  238.     TempBucket Data;  
  239.     DWORD   nCount = 0;  
  240.   
  241.     _DecodeRaw(Data, Decode);  
  242.   
  243.     for(int ii = 0; ii < 3; ii ++ )  
  244.     {  
  245.         pBuffer[ii] = Data.nData[ii];  
  246.         if (pBuffer[ii] != 255)  
  247.             nCount ++ ;  
  248.     }  
  249.   
  250.     return nCount;  
  251. }  
  252.   
  253.   
  254. void CBase64::_EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)  
  255. {  
  256.     TempBucket Data;  
  257.   
  258.     _EncodeRaw(Data, Decode);  
  259.   
  260.     for(int ii = 0; ii < 4; ii ++ )  
  261.         pBuffer[ii] = Base64Digits[Data.nData[ii]];  
  262.   
  263.     switch(Decode.nSize)  
  264.     {  
  265.     case 1:  
  266.         pBuffer[2] = '=';  
  267.   
  268.     case 2:  
  269.         pBuffer[3] = '=';  
  270.     }  
  271. }  
  272.   
  273. void CBase64::_DecodeRaw(TempBucket &Data, const TempBucket &Decode)  
  274. {  
  275.     BYTE   nTemp;  
  276.   
  277.     Data.nData[0] = Decode.nData[0];  
  278.     Data.nData[0] <<= 2;  
  279.   
  280.     nTemp = Decode.nData[1];  
  281.     nTemp >>= 4;  
  282.     nTemp &= 0x03;  
  283.     Data.nData[0] |= nTemp;  
  284.   
  285.     Data.nData[1] = Decode.nData[1];  
  286.     Data.nData[1] <<= 4;  
  287.   
  288.     nTemp = Decode.nData[2];  
  289.     nTemp >>= 2;  
  290.     nTemp &= 0x0F;  
  291.     Data.nData[1] |= nTemp;  
  292.   
  293.     Data.nData[2] = Decode.nData[2];  
  294.     Data.nData[2] <<= 6;  
  295.     nTemp = Decode.nData[3];  
  296.     nTemp &= 0x3F;  
  297.     Data.nData[2] |= nTemp;  
  298. }  
  299.   
  300. void CBase64::_EncodeRaw(TempBucket &Data, const TempBucket &Decode)  
  301. {  
  302.     BYTE   nTemp;  
  303.   
  304.     Data.nData[0] = Decode.nData[0];  
  305.     Data.nData[0] >>= 2;  
  306.   
  307.     Data.nData[1] = Decode.nData[0];  
  308.     Data.nData[1] <<= 4;  
  309.     nTemp = Decode.nData[1];  
  310.     nTemp >>= 4;  
  311.     Data.nData[1] |= nTemp;  
  312.     Data.nData[1] &= 0x3F;  
  313.   
  314.     Data.nData[2] = Decode.nData[1];  
  315.     Data.nData[2] <<= 2;  
  316.   
  317.     nTemp = Decode.nData[2];  
  318.     nTemp >>= 6;  
  319.   
  320.     Data.nData[2] |= nTemp;  
  321.     Data.nData[2] &= 0x3F;  
  322.   
  323.     Data.nData[3] = Decode.nData[2];  
  324.     Data.nData[3] &= 0x3F;  
  325. }  
  326.   
  327. BOOL CBase64::_IsBadMimeChar(BYTE nData)  
  328. {  
  329.     switch(nData)  
  330.     {  
  331.     case '\r'case '\n'case '\t'case ' ' :  
  332.     case '\b'case '\a'case '\f'case '\v':  
  333.         return TRUE;  
  334.   
  335.     default:  
  336.         return FALSE;  
  337.     }  
  338. }  
  339.   
  340. void CBase64::_Init()  
  341. {   
  342.     // Initialize Decoding table.  
  343.     int ii;  
  344.   
  345.     for(ii = 0; ii < 256; ii ++ )  
  346.         CBase64::m_DecodeTable[ii] = -2;  
  347.   
  348.     for(ii = 0; ii < 64; ii ++ )  
  349.     {  
  350.         CBase64::m_DecodeTable[Base64Digits[ii]]   = (CHAR)ii;  
  351.         CBase64::m_DecodeTable[Base64Digits[ii]|0x80] = (CHAR)ii;  
  352.     }  
  353.   
  354.     CBase64::m_DecodeTable['=']     = -1;  
  355.   
  356.     CBase64::m_DecodeTable['='|0x80]   = -1;  
  357.   
  358.     CBase64::m_Init = TRUE;  
  359. }  


文/yanxin8原创,获取更多信息请访问http://yanxin8.com/277.html

0 0
原创粉丝点击