Base64编解码

Base64编解码:C++

     

/************************************************************
*
*	Base64编解码
*
*************************************************************/

static const char s_achBase64Table[] = 
{ 
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
	'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
	'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
	'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '=' 
};

static char GetCharByIndex(unsigned char byIndex)
{
	return s_achBase64Table[byIndex];
}

static unsigned char GetIndexByChar(char ch)
{
	
	if (ch >= 'A' && ch <= 'Z')
	{
		return (unsigned char)(ch - 'A');
	}
	else if (ch >= 'a' && ch <= 'z')
	{
		return (unsigned char)(ch - 'a') + 26;
	}
	else if (ch >= '0' && ch <= '9')
	{
		return (unsigned char)(ch - '0') + 52;
	}

	if (ch == '+')
	{
		return 61;
	}

	if (ch == '/')
	{
		return 62;
	}

	if (ch == '=')
	{
		return 63;
	}

	return 0;
}

/*
base64编码说明:  取输入流中连续的3个字节A、B、C作为一组, 步骤如下:

1、首先取A、B、C对应的二进制值拼成24位二进制码
2、以6位为一组,将24位二进制码分4组,每组6位前补00构成1个字节,这样得到4个值在0 ~ 2^6之间的字节,
3、这四个字节的十进制值作为数组索引,查表得到s_base64_table中对应的字符,得到的四个字符即3字节输入的编码输出

note:
   
   如果余下一个字 符,前6个bit转换成一个Base64字符,剩下的低2位右边补0构成6bit, 然后转换成Base64,
   在输出缓冲的最后补上两个'='。  
	  
   如果余下两个字符,前12个bit转换成两个Base64字符后,剩下4个bit右边补0凑成6bit,然后转换成Base64,
   在输出缓冲末尾要补上一个'=' 。
*/

int Base64Encode(const char *pchStrIn, char *pchOut, unsigned int dwLen, unsigned int &dwOutLen)
{
	int nSrcLen = strlen(pchStrIn);
	if (nSrcLen == 0 || NULL == pchOut)
	{
		return -1; 
	}

	int nRoundCount = nSrcLen / 3;
	int nLeft = nSrcLen % 3;

	dwOutLen = nRoundCount * 4;
	if (nLeft != 0)
	{
		dwOutLen += 4;
	}

	if (dwLen < dwOutLen)
	{
		return -1;
	}

	char *pchTmp = pchOut;

	for (int i = 0; i < nRoundCount; i++)
	{
		unsigned int dwOffset = i * 3;
		
		//00XXXXXX 00XXxxxx 00xxxxXX 00XXXXXX
		
		unsigned char byA = pchStrIn[dwOffset];
		unsigned char byB = pchStrIn[dwOffset + 1];
		unsigned char byC = pchStrIn[dwOffset + 2];

		pchTmp[0] = GetCharByIndex( byA >> 2 );
		pchTmp[1] = GetCharByIndex( (byA & 0x03) << 4 | byB >> 4 );
		pchTmp[2] = GetCharByIndex( (byB & 0x0f) << 2 | byC >> 6 );
		pchTmp[3] = GetCharByIndex( byC & 0x3f );

		pchTmp += 4;
	}

	if (nLeft == 1)
	{
		unsigned int dwOffset = nRoundCount * 3;

		unsigned char byA = pchStrIn[dwOffset];

		pchTmp[0] = GetCharByIndex(byA >> 2);
		pchTmp[1] = GetCharByIndex((byA & 0x03) << 4);
		pchTmp[2] = '=';
		pchTmp[3] = '=';
	}
	else if (nLeft == 2)
	{
		unsigned int dwOffset = nRoundCount * 3;

		unsigned char byA = pchStrIn[dwOffset];
		unsigned char byB = pchStrIn[dwOffset + 1];

		pchTmp[0] = GetCharByIndex(byA >> 2);
		pchTmp[1] = GetCharByIndex((byA & 0x03) << 4 | byB >> 4);
		pchTmp[2] = GetCharByIndex((byB & 0x0f) << 2);
		pchTmp[3] = '=';
	}

	return 0;
}


int Base64Decode(const char *pchStrIn, char *pchOut, unsigned int dwLen, unsigned int &dwOutLen)
{
	int nSrcLen = strlen(pchStrIn);
	if (0 == nSrcLen || NULL == pchOut)
	{
		return -1;
	}
	
	dwOutLen = nSrcLen * 3 / 4;
	int nLeft = 0;
	int nRoundCount = nSrcLen / 4;
	if (pchStrIn[nSrcLen - 1] == '=')
	{
		if (pchStrIn[nSrcLen - 2] == '=')
		{
			dwOutLen -= 2;
			nLeft = 1;
		}
		else
		{
			nLeft = 2;
			dwOutLen -= 1;
		}

		nRoundCount--;
	}

	if (dwOutLen > dwLen)
	{
		return -1;
	}
	
	char *pchTmpOut = pchOut;
	for (int i = 0; i < nRoundCount; i++)
	{
		char *pchTmpIn =  (char*)pchStrIn + i * 4;

		unsigned char byA = GetIndexByChar(pchTmpIn[0]);
		unsigned char byB = GetIndexByChar(pchTmpIn[1]);
		unsigned char byC = GetIndexByChar(pchTmpIn[2]);
		unsigned char byD = GetIndexByChar(pchTmpIn[3]);

		//00XXXXXX 00XXxxxx 00xxxxXX 00XXXXXX

		pchTmpOut[0] = (byA << 2) | (byB >> 4);
		pchTmpOut[1] = (byB << 4) | (byC & 0x3c) >> 2;
		pchTmpOut[2] = (byC << 6) | (byD & 0x3f);

		pchTmpOut += 3;
	}

	if (nLeft == 1)
	{
		//00xxxxxx 00xx0000

		char *pchTmpIn =  (char*)pchStrIn + nRoundCount * 4;
		unsigned char byA = GetIndexByChar(pchTmpIn[0]);
		unsigned char byB = GetIndexByChar(pchTmpIn[1]);

		pchTmpOut[0] = (byA << 2) | (byB >> 4);
	}
	else if (nLeft == 2)
	{
		//00xxxxxx 00xxXXXX 00XXXX00

		char *pchTmpIn =  (char*)pchStrIn + nRoundCount * 4;
		unsigned char byA = GetIndexByChar(pchTmpIn[0]);
		unsigned char byB = GetIndexByChar(pchTmpIn[1]);
		unsigned char byC = GetIndexByChar(pchTmpIn[2]);

		pchTmpOut[0] = (byA << 2) | (byB >> 4);
		pchTmpOut[1] = (byB << 4) | (byC & 0x3c) >> 2;
	}
	
	return 0;
}

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值