#include "stdafx.h"
#include "Base64.h"

CBase64::CBase64(void)
{
}

CBase64::~CBase64(void)
{
}

const char CBase64::sm_base64digits[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

const char CBase64::sm_base64val[128] = {
	BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
	BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
	BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
	52, 53, 54, 55,  56, 57, 58, 59,  60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
	BAD,  0,  1,  2,   3,  4,  5,  6,   7,  8,  9, 10,  11, 12, 13, 14,
	15, 16, 17, 18,  19, 20, 21, 22,  23, 24, 25,BAD, BAD,BAD,BAD,BAD,
	BAD, 26, 27, 28,  29, 30, 31, 32,  33, 34, 35, 36,  37, 38, 39, 40,
	41, 42, 43, 44,  45, 46, 47, 48,  49, 50, 51,BAD, BAD,BAD,BAD,BAD
};

/************************************************************************/
/*  函数：[6/2/2016 IT];
/*  描述：将字节转换为Base64字符;
/*  参数：;
/*  	[IN] pbinary：			要转换成Base64字符的二进制字节数组;
/*  	[IN] nbinaryLen：		pbinary所指向的缓存大小;
/*  	[OUT] pOutBase64：		返回转换后的Base64字符，以'\0'结束;
/*  返回：返回转换成功后的Base64字符数;
/*  注意：注意参数1是字节BYTE,返回的pOutBase64是人为加上'\0'结束符;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
void CBase64::binToBase64(IN const unsigned char *pbinary, IN size_t nbinaryLen, OUT char *pOutBase64)
{
	for ( ; nbinaryLen >= 3; nbinaryLen -= 3, pbinary += 3) 
	{
		*pOutBase64++ = sm_base64digits[pbinary[0] >> 2];
		*pOutBase64++ = sm_base64digits[((pbinary[0] << 4) & 0x30) | (pbinary[1] >> 4)];
		*pOutBase64++ = sm_base64digits[((pbinary[1] << 2) & 0x3c) | (pbinary[2] >> 6)];
		*pOutBase64++ = sm_base64digits[pbinary[2] & 0x3f];
	}

	if (nbinaryLen > 0) 
	{
		unsigned char fragment;
		*pOutBase64++ = sm_base64digits[pbinary[0] >> 2];
		fragment = (pbinary[0] << 4) & 0x30;

		if (nbinaryLen > 1)
			fragment |= pbinary[1] >> 4;

		*pOutBase64++ = sm_base64digits[fragment];
		*pOutBase64++ = (nbinaryLen < 2) ? '=' : sm_base64digits[(pbinary[1] << 2) & 0x3c];
		*pOutBase64++ = '=';
	}
	*pOutBase64 = '\0';
}

/************************************************************************/
/*  函数：[6/2/2016 IT];
/*  描述：将Base64字符串转为化二进制字节字符串;
/*  参数：;
/*  	[IN] pBase64：		要转化成二进制字节字符串的Base64字符;
/*  	[OUT] pbinary：		返回转化成二进制字节的字符串;
/*  	[IN] maxLen：		pbinary指向的缓存大小;
/*  返回：返回转化成二进制字节字符数;
/*  注意：;
/*  示例：;
/*
/*  修改：;
/*  日期：;
/*  内容：;
/************************************************************************/
int CBase64::base64ToBin(IN const char *pBase64, OUT unsigned char *pbinary, IN size_t maxLen)
{
	size_t len = 0;
	unsigned char digit1, digit2, digit3, digit4;

	if (pBase64[0] == '+' && pBase64[1] == ' ')
		pBase64 += 2;
	if (pBase64[0] == '\r')
		return 0;

	while (*pBase64 && *pBase64 != '\r' /*&& digit4 != '='*/) 
	{
		digit1 = pBase64[0];
		if (decode64(digit1) == BAD)
			return -1;
		digit2 = pBase64[1];
		if (decode64(digit2) == BAD)
			return -1;
		digit3 = pBase64[2];
		if (digit3 != '=' && decode64(digit3) == BAD)
			return -1; 
		digit4 = pBase64[3];
		if (digit4 != '=' && decode64(digit4) == BAD)
			return -1;
		pBase64 += 4;

		++len;
		if (maxLen && len > maxLen)
			return -1;

		*(pbinary++) = (decode64(digit1) << 2) | (decode64(digit2) >> 4);
		if (digit3 != '=') 
		{
			++len;
			if (maxLen && len > maxLen)
				return -1;
			*(pbinary++) = ((decode64(digit2) << 4) & 0xf0) | (decode64(digit3) >> 2);
			if (digit4 != '=') 
			{
				++len;
				if (maxLen && len > maxLen)
					return -1;
				*(pbinary++) = ((decode64(digit3) << 6) & 0xc0) | decode64(digit4);
			} // if
		} // if
	} // while

	return len;
}
