base64编码解码讲解

一、base64
base64是一种对字符通过二进制进行编码解码转换的一种编码算法,便于在不同环境间通信,规避了乱码的出现。
在这里插入图片描述
base64算法:
1->字符串转换为三个字节一组,不足三个字节时用“=”补全
2->然后将一组三个字节的数据转换为4组6位的数据
3->转换后的每个6为数据对应base64数组的元素的位置

unsigned char base64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

ASCII码与字符间的转换
举例:将hello进行编码,分组为 1组-hel 2组->lo=
h-> 0110 1000(ascill值是104);e->0110 0101(ascill值是101)
l->0110 1100(ascill值是108);o->0110 1111(ascill值是111)
hel->011010【a】----< 000110【G】> ---- 010101 【V】--------101100【s】
lo=->011011 【b】----<000110【G】> ---- 111000 【8】--------111101【=】
编码后结果:aGVsbG8=
同理解码就是编码的逆过程
代码demon

/*********************************
**base64编码解码算法 
*********************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

unsigned char base64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


//将6位的二进制转换成ASCII值,显示出来转换后的数值
/*******************************************************************
**eg:例如1是base[53]对应的元素,而在ascii表中9的ascii十进制值是49
**所以数字的话需要减4,变为ascii数值其它同理
*********************************************************************/
static char b64_to_ascii(char str) 
{
    if (str >= 0 && str <= 25) {
        return str + 65;
    } else if (str >= 26 && str <= 51) {
        return str + 71;
    } else if (str >= 52 && str <= 61) {
        return str - 4;
    } else if (str == 62) {
        return '+';
    } else {
        return '/';
    }
}


//将二进制转换成对应的数组位数
/*******************************************************************
**eg:例如9是base[61]对应的元素,而在ascii表中9的ascii十进制值是57
**所以数字的话需要加4,变为base64的位数其它同理
*********************************************************************/
static char ascii_to_base(char str) 
{
	if (str >= 65 && str <= 90) {
		return str - 65;
	} else if (str >= 97 && str <= 122) {
		return str - 71;
	} else if (str >= 48 && str <= 57) {
		return str + 4;
	} else if (str == '+') {
		return 62;
	} else {
		return 63;
	}
}


//编码实现函数
static char *base_encode(char *src)
{
	int src_len=0;//源字符串的长度
	int divided_by_three_len=0;//除以3后的组数
	int remainder_len=0;//3取余的个数
	int encode_len=0;//编码后的长度,字节不足3个一组,补“=”符号,后长度
	int i=0;
	int encode_i=0;
	int str_i=0;

	char *str=NULL;//指向源字符串
	char *encode=NULL;//指向编码后的字符串

	str=strdup(src);//strdup,c语言中常用的一种字符串拷贝库函数,free函数成对出现。
	src_len=strlen(str);

//1.计算要转换字符串的长度,转换为3个字节为一组,6位为一个base字符的表示方式,组成4个6位为1组的形式
	divided_by_three_len=src_len/3;
	remainder_len=src_len%3;
	encode_len=(divided_by_three_len*4)+(src_len ? 4:0);//3个字节转换后的长度是4,加上取余不为0的补=号取4

	encode=malloc(encode_len+1);//长度加'/0'
	bzero(encode,encode_len+1);

//2.因为3转换四,故按组数循环,补=号的另做讨论,这里要转换成二进制,再转换为base64对应的二进制显示出来
	for (i = 0; i <divided_by_three_len * 3; i += 3) {
		encode[encode_i] = b64_to_ascii((str[i] & 0xFF) >> 2);//被转换的字符右移2位得到第一个6位对应base64表字符
		encode[encode_i+1] = b64_to_ascii(((str[i] & 0x03) << 4) | ((str[i + 1] & 0xFF) >> 4));//得到第一个字节的后2位与第二个字节的前4位组成一个6位二进制数
		encode[encode_i+2] = b64_to_ascii(((str[i + 1] & 0x0F) << 2) | ((str[i + 2] & 0xFF) >> 6));//得到第二个字节的低4位与第3个字节的高2位,组成一个6位二进制数
		encode[encode_i+3] = b64_to_ascii(str[i + 2] & 0x3F);//得到第二个字节的低4位与第3个字节的高2位
		encode_i+=4;
	}
	
	if (remainder_len == 1) {
		encode[encode_i] = b64_to_ascii((str[i] & 0xFF) >> 2);//被转换的字符右移2位得到第一个6位对应base64表字符;
		encode[encode_i+1] = b64_to_ascii((str[i] & 0x03) << 4);//得到第一个字节的后2位变为6位的高2位
		encode[encode_i+2] = '=';
		encode[encode_i+3] = '=';
	} else if (remainder_len == 2){
		encode[encode_i] = b64_to_ascii((str[i] & 0xFF) >> 2);//被转换的字符右移2位得到第一个6位对应base64表字符
		encode[encode_i+1] = b64_to_ascii(((str[i] & 0x03) << 4) | ((str[i + 1] & 0xFF) >> 4));//得到第一个字节的后2位与第二个字节的前4位的一个6位二进
		encode[encode_i+2] = b64_to_ascii((str[i + 1] & 0x0F) << 2);//第二个字节的低4位转换为高四位的6位
		encode[encode_i+3] = '=';
	}
		
	if(str){
		free(str);
		str=NULL;
	}

	return encode;
}

//解码实现函数
static char *base_decode(char *src)
{
	int src_len=0;//源字符串的长度
	int decode_len=0;//解码后的字符长度
	char *decode=NULL;
	char *encode=NULL;
	int i=0;
	int decode_i=0;

	src_len=strlen(src);
	printf("src_len is %d\n",src_len);
	if((src[src_len-2]=='=')&&(src[src_len-1]=='='))
	{
		decode_len=src_len/4*3-2;
	}else if((src[src_len-1]=='=') && (src[src_len-2]!='=')){
		decode_len=src_len/4*3-1;
	}else
		decode_len=src_len/4*3;
	printf("decode_len is %d\n",decode_len);
	
	encode = strdup(src);
	decode=malloc(src_len+1);
	bzero(decode,src_len+1);

//以4个字符为一组解码,得到3个字节一组的源码
	for(i=0;i<src_len;i+=4)
	{
		decode[decode_i]=(((ascii_to_base(encode[i])&0xff)<<2) | ((ascii_to_base(encode[i+1])&0xff)>>4));//计算第一个字节
		if(src[i+2]=='=')
		{
			break;
		}
		decode[decode_i+1]=(((ascii_to_base(encode[i+1])&0xff)<<4) | ((ascii_to_base(encode[i+2])&0xff)>>2));//计算第二个字节
		if(src[i+3]=='=')
		{
			break;
		}
		decode[decode_i+2]=(((ascii_to_base(encode[i+2])&0xff)<<6) | (ascii_to_base(encode[i+3])&0xff));//计算第三个字节
		decode_i+=3;
	}
	if(encode)
	{
		free(encode);
		encode=NULL;
	}
	return decode;
}


int main(int argc,char **argv)
{
	char *encode=NULL;
	encode=base_encode(argv[1]);
	printf("=====encode is :%s \n",encode);
	printf("=====decode is :%s \n",base_decode(encode));

	return 0;
}

运行结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值