算法系列8《Base64》
来源:互联网 发布:网络的利与弊 编辑:程序博客网 时间:2024/05/21 17:23
目录(?)[-]
- Base64索引表
- C实现代码
- Base64h
- 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?
- // Base64.h
- #pragma once
- #include <windows.h>
- class CBase64
- {
- // Internal bucket class.
- class TempBucket
- {
- public:
- BYTE nData[4];
- BYTE nSize;
- void Clear() { ::ZeroMemory(nData, 4); nSize = 0; };
- };
- PBYTE m_pDBuffer;
- PBYTE m_pEBuffer;
- DWORD m_nDBufLen;
- DWORD m_nEBufLen;
- DWORD m_nDDataLen;
- DWORD m_nEDataLen;
- public:
- CBase64();
- virtual ~CBase64();
- public:
- virtual PBYTE Encode(const PBYTE, DWORD);
- virtual PBYTE Decode(const PBYTE, DWORD);
- virtual CString Encode(LPCSTR sMessage);
- virtual CString Decode(LPCSTR sMessage);
- virtual LPCSTR DecodedMessage() const;
- virtual LPCSTR EncodedMessage() const;
- virtual void AlloCEncodeDlg(DWORD);
- virtual void AllocDecode(DWORD);
- virtual void SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen);
- virtual void SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen);
- protected:
- virtual void _EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);
- virtual ULONG _DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);
- virtual void _EncodeRaw(TempBucket &, const TempBucket &);
- virtual void _DecodeRaw(TempBucket &, const TempBucket &);
- virtual BOOL _IsBadMimeChar(BYTE);
- static char m_DecodeTable[256];
- static BOOL m_Init;
- void _Init();
- };
2. 《CBase64.cpp》
[cpp] view plaincopyprint?
- // CBase64.cpp
- // CBase64.cpp: implementation of the CBase64 class.
- //////////////////////////////////////////////////////////////////////
- #include "stdAfx.h"
- #include "Base64.h"
- #include "DataX.h"
- using namespace DataX;
- // Digits...
- static char Base64Digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- BOOL CBase64::m_Init = FALSE;
- char CBase64::m_DecodeTable[256];
- #ifndef PAGESIZE
- #define PAGESIZE 4096
- #endif
- #ifndef ROUNDTOPAGE
- #define ROUNDTOPAGE(a) ((((a) / 4096) + 1) * 4096)
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CBase64::CBase64()
- : m_pDBuffer(NULL),
- m_pEBuffer(NULL),
- m_nDBufLen(0),
- m_nEBufLen(0)
- {
- }
- CBase64::~CBase64()
- {
- if (m_pDBuffer != NULL)
- {
- delete [] m_pDBuffer;
- }
- if (m_pEBuffer != NULL)
- {
- delete [] m_pEBuffer;
- }
- }
- LPCSTR CBase64::DecodedMessage() const
- {
- return (LPCSTR) m_pDBuffer;
- }
- LPCSTR CBase64::EncodedMessage() const
- {
- return (LPCSTR) m_pEBuffer;
- }
- void CBase64::AlloCEncodeDlg(DWORD nSize)
- {
- if (m_nEBufLen < nSize)
- {
- if (m_pEBuffer != NULL)
- delete [] m_pEBuffer;
- m_nEBufLen = ROUNDTOPAGE(nSize);
- m_pEBuffer = new BYTE[m_nEBufLen];
- }
- ::ZeroMemory(m_pEBuffer, m_nEBufLen);
- m_nEDataLen = 0;
- }
- void CBase64::AllocDecode(DWORD nSize)
- {
- if (m_nDBufLen < nSize)
- {
- if (m_pDBuffer != NULL)
- {
- delete [] m_pDBuffer;
- }
- m_nDBufLen = ROUNDTOPAGE(nSize);
- m_pDBuffer = new BYTE[m_nDBufLen];
- }
- ::ZeroMemory(m_pDBuffer, m_nDBufLen);
- m_nDDataLen = 0;
- }
- void CBase64::SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen)
- {
- DWORD ii = 0;
- AlloCEncodeDlg(nBufLen);
- while(ii < nBufLen)
- {
- if (!_IsBadMimeChar(pBuffer[ii]))
- {
- m_pEBuffer[m_nEDataLen] = pBuffer[ii];
- m_nEDataLen ++ ;
- }
- ii ++ ;
- }
- }
- void CBase64::SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen)
- {
- AllocDecode(nBufLen);
- ::CopyMemory(m_pDBuffer, pBuffer, nBufLen);
- m_nDDataLen = nBufLen;
- }
- PBYTE CBase64::Encode(const PBYTE pBuffer, DWORD nBufLen)
- {
- SetDecodeBuffer(pBuffer, nBufLen);
- AlloCEncodeDlg(nBufLen * 2);
- TempBucket Raw;
- DWORD nIndex = 0;
- while((nIndex + 3) <= nBufLen)
- {
- Raw.Clear();
- ::CopyMemory(&Raw, m_pDBuffer + nIndex, 3);
- Raw.nSize = 3;
- _EncodeToBuffer(Raw, m_pEBuffer + m_nEDataLen);
- nIndex += 3;
- m_nEDataLen += 4;
- }
- if (nBufLen > nIndex)
- {
- Raw.Clear();
- Raw.nSize = (BYTE) (nBufLen - nIndex);
- ::CopyMemory(&Raw, m_pDBuffer + nIndex, nBufLen - nIndex);
- _EncodeToBuffer(Raw, m_pEBuffer + m_nEDataLen);
- m_nEDataLen += 4;
- }
- return m_pEBuffer;
- }
- CString CBase64::Encode(LPCSTR szMessage)
- {
- CString strHex = _T("");
- if (szMessage != NULL)
- {
- CBase64::Encode((const PBYTE)szMessage, lstrlenA(szMessage));
- if (m_nEDataLen > 0)
- {
- AscToHex(m_pEBuffer, m_nEDataLen, strHex);
- }
- }
- return strHex;
- }
- PBYTE CBase64::Decode(const PBYTE pBuffer, DWORD dwBufLen)
- {
- if (!CBase64::m_Init)
- _Init();
- SetEncodeBuffer(pBuffer, dwBufLen);
- AllocDecode(dwBufLen);
- TempBucket Raw;
- DWORD nIndex = 0;
- while((nIndex + 4) <= m_nEDataLen)
- {
- Raw.Clear();
- Raw.nData[0] = CBase64::m_DecodeTable[m_pEBuffer[nIndex]];
- Raw.nData[1] = CBase64::m_DecodeTable[m_pEBuffer[nIndex + 1]];
- Raw.nData[2] = CBase64::m_DecodeTable[m_pEBuffer[nIndex + 2]];
- Raw.nData[3] = CBase64::m_DecodeTable[m_pEBuffer[nIndex + 3]];
- if (Raw.nData[2] == 255)
- Raw.nData[2] = 0;
- if (Raw.nData[3] == 255)
- Raw.nData[3] = 0;
- Raw.nSize = 4;
- _DecodeToBuffer(Raw, m_pDBuffer + m_nDDataLen);
- nIndex += 4;
- m_nDDataLen += 3;
- }
- // If nIndex < m_nEDataLen, then we got a decode message without padding.
- // We may want to throw some kind of warning here, but we are still required
- // to handle the decoding as if it was properly padded.
- if (nIndex < m_nEDataLen)
- {
- Raw.Clear();
- for(DWORD ii = nIndex; ii < m_nEDataLen; ii ++ )
- {
- Raw.nData[ii - nIndex] = CBase64::m_DecodeTable[m_pEBuffer[ii]];
- Raw.nSize ++ ;
- if (Raw.nData[ii - nIndex] == 255)
- Raw.nData[ii - nIndex] = 0;
- }
- _DecodeToBuffer(Raw, m_pDBuffer + m_nDDataLen);
- m_nDDataLen += (m_nEDataLen - nIndex);
- }
- return m_pDBuffer;
- }
- CString CBase64::Decode(LPCSTR pszMessage)
- {
- if (!pszMessage)
- {
- return _T("");
- }
- CBase64::Decode((const PBYTE)pszMessage, lstrlenA(pszMessage));
- CString strHex = _T("");
- if (m_nDDataLen > 0)
- {
- AscToHex(m_pDBuffer, m_nDDataLen, strHex);
- }
- return strHex;
- }
- DWORD CBase64::_DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)
- {
- TempBucket Data;
- DWORD nCount = 0;
- _DecodeRaw(Data, Decode);
- for(int ii = 0; ii < 3; ii ++ )
- {
- pBuffer[ii] = Data.nData[ii];
- if (pBuffer[ii] != 255)
- nCount ++ ;
- }
- return nCount;
- }
- void CBase64::_EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)
- {
- TempBucket Data;
- _EncodeRaw(Data, Decode);
- for(int ii = 0; ii < 4; ii ++ )
- pBuffer[ii] = Base64Digits[Data.nData[ii]];
- switch(Decode.nSize)
- {
- case 1:
- pBuffer[2] = '=';
- case 2:
- pBuffer[3] = '=';
- }
- }
- void CBase64::_DecodeRaw(TempBucket &Data, const TempBucket &Decode)
- {
- BYTE nTemp;
- Data.nData[0] = Decode.nData[0];
- Data.nData[0] <<= 2;
- nTemp = Decode.nData[1];
- nTemp >>= 4;
- nTemp &= 0x03;
- Data.nData[0] |= nTemp;
- Data.nData[1] = Decode.nData[1];
- Data.nData[1] <<= 4;
- nTemp = Decode.nData[2];
- nTemp >>= 2;
- nTemp &= 0x0F;
- Data.nData[1] |= nTemp;
- Data.nData[2] = Decode.nData[2];
- Data.nData[2] <<= 6;
- nTemp = Decode.nData[3];
- nTemp &= 0x3F;
- Data.nData[2] |= nTemp;
- }
- void CBase64::_EncodeRaw(TempBucket &Data, const TempBucket &Decode)
- {
- BYTE nTemp;
- Data.nData[0] = Decode.nData[0];
- Data.nData[0] >>= 2;
- Data.nData[1] = Decode.nData[0];
- Data.nData[1] <<= 4;
- nTemp = Decode.nData[1];
- nTemp >>= 4;
- Data.nData[1] |= nTemp;
- Data.nData[1] &= 0x3F;
- Data.nData[2] = Decode.nData[1];
- Data.nData[2] <<= 2;
- nTemp = Decode.nData[2];
- nTemp >>= 6;
- Data.nData[2] |= nTemp;
- Data.nData[2] &= 0x3F;
- Data.nData[3] = Decode.nData[2];
- Data.nData[3] &= 0x3F;
- }
- BOOL CBase64::_IsBadMimeChar(BYTE nData)
- {
- switch(nData)
- {
- case '\r': case '\n': case '\t': case ' ' :
- case '\b': case '\a': case '\f': case '\v':
- return TRUE;
- default:
- return FALSE;
- }
- }
- void CBase64::_Init()
- {
- // Initialize Decoding table.
- int ii;
- for(ii = 0; ii < 256; ii ++ )
- CBase64::m_DecodeTable[ii] = -2;
- for(ii = 0; ii < 64; ii ++ )
- {
- CBase64::m_DecodeTable[Base64Digits[ii]] = (CHAR)ii;
- CBase64::m_DecodeTable[Base64Digits[ii]|0x80] = (CHAR)ii;
- }
- CBase64::m_DecodeTable['='] = -1;
- CBase64::m_DecodeTable['='|0x80] = -1;
- CBase64::m_Init = TRUE;
- }
文/yanxin8原创,获取更多信息请访问http://yanxin8.com/277.html
0 0
- 算法系列8《Base64》
- C++ VC Base64编解码算法系列二(编码算法)
- C++ VC Base64编解码算法系列三(解码算法)
- 算法系列(十一)BASE64算法实现和使用说明
- Base64算法
- base64算法
- base64算法
- Base64算法
- Base64算法
- Base64算法
- BASE64算法
- Base64算法
- Base64算法
- Base64算法
- Base64算法
- Base64系列第一篇 Base64介绍
- Base64系列第一篇 Base64介绍
- C++ VC Base64编解码算法系列一(基本数据定义)
- awk print函数
- [OI回忆录系列之一]序言和人物
- ipa使用企业账号重签名并支持推送
- 调侃面向对象编程的23种设计模式
- 一个笔记记下一个资料链接
- 算法系列8《Base64》
- (素材源码)猫猫学IOS(十六)UI之XIB自定义Cell实现团购UI
- C++之旅 虚函数
- Java学习笔记1 HelloWorld
- Windows Server 2003 下配置 MySQL 群集(Cluster)
- Redis源码中探秘SHA-1算法原理及其编程实现
- 大巧不工Web前端设计修炼之道——(2)打造前端设计的基石,交出你的原型稿
- 认认真真写博客
- 不错的PHP解密和美化网站