天天看点

BASE64编码and解码的C实现

#include "stdio.h"
#include "string.h"

static char base64_encode_map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 

static int base64_decode_map[256] = {
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 
	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, 
	-1,  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, -1, -1, -1, -1, -1, 
	-1, 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, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
};

/* ZhangYaMin
 * #base64 编码
 * @param sInput 输入字符串
 * @param iLen 输入字符串长度
 * @param sOutput 输出字符串
 */
int base64_encode(const unsigned char *sInput, const int iLen, unsigned char *sOutput)
{
	if (sInput == NULL || sOutput==NULL || iLen <= 0) return -1;

	//保证逻辑右移
	unsigned char *p = (unsigned char *)sInput;
	unsigned char *pOut = sOutput;
	unsigned char *pEnd = (unsigned char *)sInput + iLen;

	while (pEnd - p >= 3) {
		*pOut++ = base64_encode_map[( p[0] >> 2 )];
		*pOut++ = base64_encode_map[( (p[0] << 4) & 0x30 ) | ( p[1] >> 4 )];
		*pOut++ = base64_encode_map[( (p[1] << 2) & 0x3C ) | ( p[2] >> 6 )];
		*pOut++ = base64_encode_map[p[2] & 0x3F];
		p += 3;
	}

	if (pEnd - p > 0) {
		*pOut++ = base64_encode_map[(p[0] >> 2)];
		if (pEnd - p == 2) {
			*pOut++ = base64_encode_map[( (p[0] << 4) & 0x30 ) | ( p[1] >> 4 )];
			*pOut++ = base64_encode_map[(p[1] << 2) & 0x3C]; 
			*pOut++ = '=';
		} else if (pEnd - p == 1) {
			*pOut++ = base64_encode_map[(p[1] << 4) & 0x30];
			*pOut++ = '=';
			*pOut++ = '=';
		}
	}

	return 0;
}

/* ZhangYaMin
 * #base64 解码
 * @param sInput 输入base64字符串
 * @param sOutput 输出字符串
 */
int base64_decode(const unsigned char* sInput,unsigned char *sOutput)
{
	if (sInput == NULL || sOutput == NULL) return -1;

	int iInputLen = strlen(sInput);
	if (iInputLen < 4 || iInputLen % 4 != 0) return -1;

	//保证逻辑右移
	unsigned char *p = (unsigned char*)sInput;
	unsigned char *pOut = sOutput;
	unsigned char *pEnd = (unsigned char*)sInput + iInputLen;
	for (; p < pEnd; p += 4) {
		*pOut++ = ((base64_decode_map[p[0]] << 2) & 0xFC) | ((base64_decode_map[p[1]] >> 4) & 0x03);
		*pOut++ = ((base64_decode_map[p[1]] << 4) & 0xF0) | ((base64_decode_map[p[2]] >> 2) & 0x0F);
		*pOut++ = ((base64_decode_map[p[2]] << 6) & 0xC0) | (base64_decode_map[p[3]]); 
	}

	if (*(sInput + iInputLen - 2) == '=') {
		*(pOut - 2) = '\0';
	} else if (*(sInput + iInputLen - 1) == '=') {
		*(pOut - 1) = '\0';
	}

	return 0;
}