• base 64 编解码器


    base 64 编解码

    1. base64的编码都是按字符串长度,以每3个8bit的字符为一组,

    2. 然后针对每组。首先获取每一个字符的ASCII编码。

    3. 然后将ASCII编码转换成8bit的二进制,得到一组3*8=24bit的字节

    4. 然后再将这24bit划分为4个6bit的字节,并在每一个6bit的字节前面都填两个高位0。得到4个8bit的字节

    5. 然后将这4个8bit的字节转换成10进制。对比Base64编码表 (下表)。得到相应编码后的字符。



    实现:

    //////////////////////////////////////////////////////////////////////
    //
    // base64 Encoding/Decoding:
    //	 Encoding: String2Base64: unsigned char *  to base64;
    //	 Decoding: Base642TString: base64 to unsigned char * .
    //
    // xuhh
    // Dec 11, 2014
    //
    //////////////////////////////////////////////////////////////////////
    
    #if !defined(_MIME_CODING_H)
    #define _MIME_CODING_H
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    #include <utility>
    #include <string>
    #include <list>
    using namespace std;
    
    #if !defined(ASSERT)
    #if defined(_DEBUG)
    	#include <assert.h>
    	#define ASSERT(exp)	assert(exp)
    #else
    	#define ASSERT(exp)	((void)0)
    #endif
    #endif
    
    #if defined(_DEBUG) && !defined(DEBUG_NEW)
    #define DEBUG_NEW new
    #endif
    
    // maximum length of an encoded line (RFC 2045)
    #define MAX_MIME_LINE_LEN	76
    #define MAX_ENCODEDWORD_LEN	75
    
    
    //////////////////////////////////////////////////////////////////////
    // string to base64
    
    extern unsigned char * String2Base64(const char* str);
    
    //////////////////////////////////////////////////////////////////////
    // base64 to string
    
    extern unsigned char * Base642TString(const char* str);
    
    //////////////////////////////////////////////////////////////////////
    // CMimeEnvironment - global environment to manage encoding/decoding
    
    class CMimeCodeBase;
    
    #define DECLARE_MIMECODER(class_name) 
    	public: static CMimeCodeBase* CreateObject() { return new class_name; }
    
    
    //////////////////////////////////////////////////////////////////////
    // CMimeCodeBase
    
    class CMimeCodeBase
    {
    public:
    	CMimeCodeBase() :
    		m_pbInput(NULL),
    		m_nInputSize(0),
    		m_bIsEncoding(false) {}
    
    public:
    	void SetInput(const char* pbInput, int nInputSize, bool bEncoding)
    	{
    		m_pbInput = (const unsigned char*) pbInput;
    		m_nInputSize = nInputSize;
    		m_bIsEncoding = bEncoding;
    	}
    	int GetOutputLength() const
    	{
    		return m_bIsEncoding ?

    GetEncodeLength() : GetDecodeLength(); } int GetOutput(unsigned char* pbOutput, int nMaxSize) { return m_bIsEncoding ?

    Encode(pbOutput, nMaxSize) : Decode(pbOutput, nMaxSize); } protected: // overrides virtual int GetEncodeLength() const { return m_nInputSize; } virtual int GetDecodeLength() const { return m_nInputSize; } virtual int Encode(unsigned char* pbOutput, int nMaxSize) const { int nSize = min(nMaxSize, m_nInputSize); ::memcpy(pbOutput, m_pbInput, nSize); return nSize; } virtual int Decode(unsigned char* pbOutput, int nMaxSize) { return CMimeCodeBase::Encode(pbOutput, nMaxSize); } protected: const unsigned char* m_pbInput; int m_nInputSize; bool m_bIsEncoding; }; ////////////////////////////////////////////////////////////////////// // CMimeCodeBase64 - for base64 encoding mechanism class CMimeCodeBase64 : public CMimeCodeBase { public: CMimeCodeBase64() : m_bAddLineBreak(true) {} public: DECLARE_MIMECODER(CMimeCodeBase64) void AddLineBreak(bool bAdd=true) { m_bAddLineBreak = bAdd; } protected: virtual int GetEncodeLength() const; virtual int GetDecodeLength() const; virtual int Encode(unsigned char* pbOutput, int nMaxSize) const; virtual int Decode(unsigned char* pbOutput, int nMaxSize); private: bool m_bAddLineBreak; private: static inline int DecodeBase64Char(unsigned int nCode) { if (nCode >= 'A' && nCode <= 'Z') return nCode - 'A'; if (nCode >= 'a' && nCode <= 'z') return nCode - 'a' + 26; if (nCode >= '0' && nCode <= '9') return nCode - '0' + 52; if (nCode == '+') return 62; if (nCode == '/') return 63; return 64; } }; #endif // !defined(_MIME_CODING_H)




    实现文件:



    //////////////////////////////////////////////////////////////////////
    //
    // base64 Encoding/Decoding:
    //	 Encoding: String2Base64: unsigned char *  to base64;
    //	 Decoding: Base642TString: base64 to unsigned char * .
    //
    // xuhh
    // Dec 11, 2014
    //
    //////////////////////////////////////////////////////////////////////
    #include "MimeCode.h"
    
    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif
    
    
    //////////////////////////////////////////////////////////////////////////
    // string to base64
    unsigned char* String2Base64(const char * szStr)
    {
    	CMimeCodeBase64 base64;
    	base64.SetInput(szStr, strlen(szStr), true);
    	int nLen = base64.GetOutputLength()+1;
    	unsigned char* pOutput = new unsigned char[nLen];
    	nLen = base64.GetOutput(pOutput, nLen);
    	pOutput[nLen] = 0;
    	return pOutput;
    }
    
    
    //////////////////////////////////////////////////////////////////////////
    // base64 to string
    
    unsigned char *  Base642TString(const char* str)
    {
    	CMimeCodeBase64 base64;
    	base64.SetInput(str, strlen(str), false);
    	int len = base64.GetOutputLength()+1;
    	unsigned char* pOutput = new unsigned char[len];
    	len = base64.GetOutput(pOutput, len);
    	pOutput[len] = 0;
    	return pOutput;
    }
    
    //////////////////////////////////////////////////////////////////////
    // CMimeCodeBase64
    
    int CMimeCodeBase64::GetEncodeLength() const
    {
    	int nLength = (m_nInputSize + 2) / 3 * 4;
    	if (m_bAddLineBreak)
    		nLength += (nLength / MAX_MIME_LINE_LEN + 1) * 2;
    	return nLength;
    }
    
    int CMimeCodeBase64::GetDecodeLength() const
    {
    	return m_nInputSize * 3 / 4 + 2;
    }
    
    int CMimeCodeBase64::Encode(unsigned char* pbOutput, int nMaxSize) const
    {
    	static const char* s_Base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
    	unsigned char* pbOutStart = pbOutput;
    	unsigned char* pbOutEnd = pbOutput + nMaxSize;
    	int nFrom, nLineLen = 0;
    	unsigned char chHigh4bits = 0;
    
    	for (nFrom=0; nFrom<m_nInputSize; nFrom++)
    	{
    		if (pbOutput >= pbOutEnd)
    			break;
    
    		unsigned char ch = m_pbInput[nFrom];
    		switch (nFrom % 3)
    		{
    		case 0:
    			*pbOutput++ = s_Base64Table[ch >> 2];
    			chHigh4bits = (ch << 4) & 0x30;
    			break;
    
    		case 1:
    			*pbOutput++ = s_Base64Table[chHigh4bits | (ch >> 4)];
    			chHigh4bits = (ch << 2) & 0x3c;
    			break;
    
    		default:
    			*pbOutput++ = s_Base64Table[chHigh4bits | (ch >> 6)];
    			if (pbOutput < pbOutEnd)
    			{
    				*pbOutput++ = s_Base64Table[ch & 0x3f];
    				nLineLen++;
    			}
    		}
    
    		nLineLen++;
    		if (m_bAddLineBreak && nLineLen >= MAX_MIME_LINE_LEN && pbOutput+2 <= pbOutEnd)
    		{
    			*pbOutput++ = '
    ';
    			*pbOutput++ = '
    ';
    			nLineLen = 0;
    		}
    	}
    
    	if (nFrom % 3 != 0 && pbOutput < pbOutEnd)	// 不足三位。= 补足
    	{
    		*pbOutput++ = s_Base64Table[chHigh4bits];
    		int nPad = 4 - (nFrom % 3) - 1;
    		if (pbOutput+nPad <= pbOutEnd)
    		{
    			::memset(pbOutput, '=', nPad);
    			pbOutput += nPad;
    		}
    	}
    	if (m_bAddLineBreak && nLineLen != 0 && pbOutput+2 <= pbOutEnd)
    	{
    		*pbOutput++ = '
    ';
    		*pbOutput++ = '
    ';
    	}
    	return (int)(pbOutput - pbOutStart);
    }
    
    int CMimeCodeBase64::Decode(unsigned char* pbOutput, int nMaxSize)
    {
    	const unsigned char* pbData = m_pbInput;
    	const unsigned char* pbEnd = m_pbInput + m_nInputSize;
    	unsigned char* pbOutStart = pbOutput;
    	unsigned char* pbOutEnd = pbOutput + nMaxSize;
    
    	int nFrom = 0;
    	unsigned char chHighBits = 0;
    
    	while (pbData < pbEnd)
    	{
    		if (pbOutput >= pbOutEnd)
    			break;
    
    		unsigned char ch = *pbData++;
    		if (ch == '
    ' || ch == '
    ')
    			continue;
    		ch = (unsigned char) DecodeBase64Char(ch);
    		if (ch >= 64)				// invalid encoding, or trailing pad '='
    			break;
    
    		switch ((nFrom++) % 4)
    		{
    		case 0:
    			chHighBits = ch << 2;
    			break;
    
    		case 1:
    			*pbOutput++ = chHighBits | (ch >> 4);
    			chHighBits = ch << 4;
    			break;
    
    		case 2:
    			*pbOutput++ = chHighBits | (ch >> 2);
    			chHighBits = ch << 6;
    			break;
    
    		default:
    			*pbOutput++ = chHighBits | ch;
    		}
    	}
    
    	return (int)(pbOutput - pbOutStart);
    }
    


  • 相关阅读:
    Integration Services学习(3):数据流任务(下) (转自游子吟)
    delete和truncate的区别
    Integration Services 学习(6):包配置 (转自游子吟)
    SSIS 学习(2):数据流任务(上) (转自游子吟)
    Integration Services 学习(5):容器 (转自游子吟)
    Integration Services 学习(4):变量和表达式 (转自游子吟)
    in与exist , not in与not exist 的区别
    SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY
    关于Reporting Services的Q&A
    SSIS 学习(1) 概要 (转自游子吟)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5045194.html
Copyright © 2020-2023  润新知