一、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;
}
运行结果: