Base64是一种将二进制转为可打印字符的编码方法,主要用于邮件传输。Base64将64个字符(A-Z,a-z,0-9,+,/)作为基本字符集,把所有符号转换为这个字符集中的字符。
编码:
编码每次将3字节转为4字节,若输入字节数不是3的倍数,则在末尾填充0字节使其长度为3的倍数。对于3字节,每次取出6位,并在前面添加2位0构成一个字节,以此字节为下标查找Base64码表(如下图)输出对应字符。每次将3字节转为4字节(3*8=4*6),直至得到整个输入串的编码结果。最后,若之前在输入中添加了1个0字节,则将输出结果最后1字节替换成“=”,若添加了2个0字节,则将输出结果最后2字节替换成“=”。
解码:
Base64解码就是编码的逆过程,要注意解码时每个字节的前2位0是人为填充的,后6位才是有效位。每次将4字节中的24位有效位提取出来构成3字节即可。
编码解码过程的核心就是位操作。
Base64码表
代码:
#include<stdio.h> #include<stdlib.h> #include<string.h> const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int findindex(char c) { for(int i=0;i<64;i++) { if(c==table[i]) return i; } return -1; } void base64enc(const char*src,char*&dst) { int slen=strlen(src); int len=slen; if(len%3!=0)len=(len/3+1)*3;//长度凑成3的倍数 unsigned char*s=(unsigned char*)malloc(len*sizeof(unsigned char));//此处使用unsigned char,否则无法处理中文输入 memset(s,0,len); memcpy(s,src,slen); int dlen=(len/3)*4+1; dst=(char*)malloc(dlen*sizeof(char)); for(int i=0,j=0;i<len;i+=3) { //核心步骤 //************************************** dst[j]=table[s[i]>>2]; dst[j+1]=table[((s[i]&0X03)<<4)|(s[i+1]>>4)]; dst[j+2]=table[((s[i+1]&0X0F)<<2)|(s[i+2]>>6)]; dst[j+3]=table[s[i+2]&0X3F]; //************************************** j+=4; } free(s); if(slen%3==1)dst[dlen-2]=dst[dlen-3]='='; if(slen%3==2)dst[dlen-2]='='; dst[dlen-1]=0; } void base64dec(const char*src,char*&dst) { int slen=strlen(src); if(slen%4!=0)return ; int dlen=(slen/4)*3+1; char*d=(char*)malloc(dlen*sizeof(char)); int index[4]; for(int i=0,j=0;i<slen;i+=4) { for(int k=0;k<4;k++) { index[k]=findindex(src[i+k]); } //核心步骤 //************************************** d[j]=index[0]<<2|index[1]>>4; d[j+1]=index[1]<<4|index[2]>>2; d[j+2]=index[2]<<6|index[3]; //************************************** j+=3; } //去除src尾部'='的影响 if(src[slen-1]=='='&&src[slen]!='=') dlen-=1; if(src[slen-1]=='='&&src[slen]=='=') dlen-=2; dst=(char*)malloc(dlen*sizeof(char)); memcpy(dst,d,dlen); free(d); dst[dlen-1]=0; } int main() { char src[]="Hello,小罗"; char*enc,*dec; base64enc(src,enc); base64dec(enc,dec); printf("%s ",src); printf("%s ",enc); printf("%s ",dec); free(enc); free(dec); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。