Base64编解码

base64编码用64个字符表示编码后的内容,这64个字符从A到Z、a到z、0到9和+、/。每个字符用6位表示,第7、8位补0,最后2个字符在不同的实现中有不同的内容。经过base64编码的字符串长度肯定是4的的整数倍,因为它用4个字符表示每3个编码前的字符,如果编码前不足3个字符就用'='代替,最多2个'='。

对3个字符进行的编码

0010 0001 1011 01010000 1000

0000 1000 0001 10110001 01000000 1000

取第一个字节的前6位作为编码后的第一个字符,也就是0000 1000,前面补了2个0,因为要凑齐8位一个字节,

取第一个字符的后2字节和第2个字符的前4位作为第二个编码后的字符,也就是0001 1011,照样补2个0在前面,后面不说明,

取第二个字符的后4位和第三个字符的前2位作为第三个编码后的字符,也就是0001 0100,

取第三个字符的后6位作为第四个编码后的字符,也就是0000 1000。

对2个字符进行的编码(中括号中的0为补齐3字节而添加)

0010 0001 1011 0101【0000 0000】

0000 1000 0001 10110001 01000000 0000

取第一个字符的前6位作为编码后的第一个字符,也就是0000 1000

取第一个字符的后2字节和第2个字符的前4位作为编码后的字符,也就是0001 1011,

差一个字节怎么办,不用怕,补一个全0字节进去,即0000 0000,

取第二个字符的后4位和第三个的前2位作为第三个编码后的字符,也就是0001 0100,

由于补了1个字节,所以第四个编码后的字符为'='。

对1个字节进行的编码

0010 0001 【0000 0000】【0000 0000】

补2个全0字节,照样计算出前2个编码后的字符后后2个用'='填充。

base64解码就是编码的逆过程,要注意解码时每个字节的前2位都是0,都是添加进去的,不能算作有效位,只有每个字节的后6位才是有效位。

实现

在c语言中,上面的按位操作用按位与(&)和按位或(|)实现


base64编码

int base64_code(const char *src, char *dst)
{
	unsigned int i = 0;
	unsigned int j = 0; 
	int length = 0;
	char data[4];

	assert(src != NULL && dst != NULL);

	for (i = 0; i < strlen(src); i += 3)
	{
		data[0] = src[i];
		data[1] = src[i+1];
		data[2] = src[i+2];
		printf("[1] %c %c %c\r\n", data[0], data[1], data[2]);
		printf("[2] %d\r\n", strlen(data));

		if (3 == strlen(data))
		{
			dst[j]   = code_table[(data[0]>>2)&0x3f];
			dst[j+1] = code_table[((data[0]<<4)&0x30 | (data[1]>>4)&0x0f)&0x3f];
			dst[j+2] = code_table[((data[1]<<2)&0x3f | (data[2]>>6)&0x03)&0x3f];
			dst[j+3] = code_table[data[2]&0x3f];
		}
		else if (2 == strlen(data))
		{
			dst[j]   = code_table[(data[0]>>2)&0x3f];
			dst[j+1] = code_table[(data[0]<<4)&0x30 | (data[1]>>4)&0x0f];
			dst[j+2] = code_table[(data[1]<<2)&0x3f | (0>>6)&0x03];
			dst[j+3] = '=';
		}
		else if (1 == strlen(data))
		{
			dst[j]   = code_table[(data[0]>>2)&0x3f];
			dst[j+1] = code_table[(data[0]<<4)&0x30 | (0>>4)&0x0f];
			dst[j+2] = '=';
			dst[j+3] = '=';
		}
		j += 4;
		if (length + 4 > 76)
		{
			dst[j] = '\r';
			dst[j+1] = '\n';
			j += 2;
		}
	}

	return 0;
}

base64解码

unsigned int find_index(char c)
{
unsigned int i = 0;


for (i = 0; i < 64; i++)
{
if (code_table[i] == c)
{
return i;
}
}


return 80;
}


int base64_decode(const char *src, char *dst)
{
unsigned int i = 0;
unsigned int j = 0;
char data[4];
int index[4];


assert(src != NULL && dst != NULL);
if (strlen(src)%4 != 0)
{
return -1;
}


for (i = 0; i < strlen(src); i += 4)
{
data[0] = src[i];
data[1] = src[i+1];
data[2] = src[i+2];
data[3] = src[i+3];
printf("[1] %c %c %c %c\r\n", data[0], data[1], data[2], data[3]);


if (data[3] != '=')
{
index[0] = find_index(data[0]);
index[1] = find_index(data[1]);
index[2] = find_index(data[2]);
index[3] = find_index(data[3]);


dst[j]   = (index[0]<<2)&0xfc | (index[1]>>4)&0x03;
dst[j+1] = (index[1]<<4)&0xf0 | (index[2]>>2)&0x0f;
dst[j+2] = (index[2]<<6)&0xc0 | index[3];
j += 3;
}
else if (data[3] == '=' && data[2] != '=')
{
index[0] = find_index(data[0]);
index[1] = find_index(data[1]);
index[2] = find_index(data[2]);


dst[j]   = (index[0]<<2)&0xfc | (index[1]>>4)&0x03;
dst[j+1] = (index[1]<<4)&0xf0 | (index[2]>>2)&0x0f;
j += 2;
}
else if(data[3] == '=' && data[2] == '=')
{
index[0] = find_index(data[0]);
index[1] = find_index(data[1]);


dst[j]   = (index[0]<<2)&0xfc | (index[1]>>4)&0x03;
j += 1;
}
}


return 0;
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值