#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;
}