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++ = '\r';
			*pbOutput++ = '\n';
			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++ = '\r';
		*pbOutput++ = '\n';
	}
	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 == '\r' || ch == '\n')
			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);
}

时间: 2024-08-15 11:59:03

base 64 编解码的相关文章

C# base 64图片编码解码

使用WinForm实现了图片base64编码解码的 效果图: 示例base 64编码字符串: /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI

各种音视频编解码学习详解

各种音视频编解码学习详解 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等.最近因为项目的关系,需要理清媒体的codec,比较搞的是,在豆丁网上看运营商的规范 标准,同一运营商同样的业务在不同文档中不同的要求,而且有些要求就我看来应当是历史的延续,也就是现在已经很少采用了.所以豆丁上看不出所以然,从 wiki上查.中文的wiki信息量有限,很短,而wiki的英文内容内多,删减版

Base64编解码Android和ios的例子,补充JNI中的例子

1.在Android中java层提供了工具类:android.util.Base64; 里面都是静态方法,方便直接使用: 使用方法如下: Java代码   // Base64 编码: byte [] encode = Base64.encode("Hello, World".getBytes(), Base64.DEFAULT); String enc = new String(encode); Log.d("","base 64 encode = &qu

关于BASE 24 ,BASE 64原理以及实现程序

关于BASE 24 ,BASE 64原理以及实现程序 来源 https://wangye.org/blog/archives/5/ 可能很多人听说过Base64编码,很少有人听说过Base24编码,Base24编码主要应用在序列号生成上,其实基本的算法思想都是一样的,只是编码的模式有点变化.Base64所对应的编码表是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=共计64位.而Base24所对应的编码表是BCDF

利用CxImage实现编解码Gif图像代码举例

Gif(GraphicsInterchange Format,图形交换格式)是由CompuServe公司在1987年开发的图像文件格式,分为87a和89a两种版本.Gif是基于LZW算法的无损压缩算法.Gif图像是基于颜色表的,最多只支持8位(256色).Gif减少了图像调色板中的色彩数量,从而在存储时达到减少图像文件大小的目的.Gif分为静态Gif和动画Gif两种,扩展名为.gif,是一种压缩位图格式,支持透明背景图像,适用于多种操作系统. 下面利用CxImage开源库,实现对Gif图像进行编

openssl命令行Base64编解码

openssl对base64编解码的规范支持较差,用它编解码的结果别的语言如php处理很不方便,注意的几点整理如下 1,如果php加密结果做base64编码长度小于64,则需要添加一个换行符openssl才能解码: 2,php需要对base64编码结果每隔64个字符插入一个换行符,openssl才能解码.(原因是openssl默认bufsize缓冲区大小16k,但是一旦涉及base64的计算缓冲区只有80字节,一旦编码结果超过80字节则会计算失败,base64编解码无法更改缓冲区大小) 示例代码

视频编解码

所谓视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式.视频流传输中最为重要的编解码标准有国际电联的H.261.H.263.H.264,运动静止图像专家组的M-JPEG和国际标准化组织运动图像专家组的MPEG系列标准,此外在互联网上被广泛应用的还有Real-Networks的RealVideo.微软公司的WMV以及Apple公司的QuickTime等. 中文名 视频编码 外文名 Video Encoding 分    类 H.26x系列,MPEG系列,AVS

【GPU编解码】GPU硬解码---DXVA

[GPU编解码]GPU硬解码---DXVA 前面介绍利用NVIDIA公司提供的CUVID库进行视频硬解码,下面将介绍利用DXVA进行硬解码. 一.DXVA介绍 DXVA是微软公司专门定制的视频加速规范,是一种接口规范.DXVA规范制定硬件加速解码可分四级:VLD,控制BitStream:IDCT,反余弦变换:Mocomp,运动补偿,Pixel Prediction:PostProc,显示后处理.其中,VLD加速等级最高,所以其包含IDCT.MoCoopm和PostProc:IDCT加速次之,包含

Windows系统下开源编解码库H.264与FFmpeg-2.8.2的编译与配置

一. 前言 FFmpeg是一个基于Linux开发的开源项目,其源代码和Windows下最常见的Visual Studio提供的C/C++编译器不兼容,因此它不支持MSVC++编译,需要在Windows下配置一个类似Linux的编译环境进行编译. 编译生成动态链接库dll,这些库将和其他的动态链接库一样在使用上没什么差别.可以使用MSVC++来链接这些库到其他的程序,也就是说,Windows + Visual Studio平台下的软件开发. 如果没有时间了解以下编译的过程,可直接下载以下链接的压缩