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\n",src);
printf("%s\n",enc);
printf("%s\n",dec);
free(enc);
free(dec);
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Base64编码与解码 分类: 中文信息处理 2014-11-03 21:58 505人阅读 评论(0) 收藏的更多相关文章

  1. XHTML 结构化:使用 XHTML 重构网站 分类: C1_HTML/JS/JQUERY 2014-07-31 15:58 249人阅读 评论(0) 收藏

    http://www.w3school.com.cn/xhtml/xhtml_structural_01.asp 我们曾经为本节撰写的标题是:"XHTML : 简单的规则,容易的方针.&qu ...

  2. OC基础:数组.字典.集 分类: ios学习 OC 2015-06-18 18:58 47人阅读 评论(0) 收藏

    ==============NSArray(不可变数组)=========== NSArray,继承自NSObject  用来管理(储存)一些有序的对象,不可变数组. 创建一个空数组 NSArray ...

  3. Hiking 分类: 比赛 HDU 函数 2015-08-09 21:24 3人阅读 评论(0) 收藏

    Hiking Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Subm ...

  4. android开发之调试技巧 分类: android 学习笔记 2015-07-18 21:30 140人阅读 评论(0) 收藏

    我们都知道,android的调试打了断点之后运行时要使用debug as->android application 但是这样的运行效率非常低,那么我们有没有快速的方法呢? 当然有. 我们打完断点 ...

  5. UI基础:UIButton.UIimage 分类: iOS学习-UI 2015-07-01 21:39 85人阅读 评论(0) 收藏

    UIButton是ios中用来响应用户点击事件的控件.继承自UIControl 1.创建控件 UIButton *button=[UIButton buttonWithType:UIButtonTyp ...

  6. UI基础:UITextField 分类: iOS学习-UI 2015-07-01 21:07 68人阅读 评论(0) 收藏

    UITextField 继承自UIControl,他是在UILabel基础上,对了文本的编辑.可以允许用户输入和编辑文本 UITextField的使用步骤 1.创建控件 UITextField *te ...

  7. 架构师速成5.1-小学gtd进阶 分类: 架构师速成 2015-06-26 21:17 313人阅读 评论(0) 收藏

    人生没有理想,那和咸鱼有什么区别. 有了理想如何去实现,这就是gtd需要解决的问题.简单说一下gtd怎么做? 确定你的目标,如果不能确定长期目标,至少需要一个2年到3年的目标. 目标必须是可以衡量的, ...

  8. 【JAVA编码专题】UNICODE,GBK,UTF-8区别 分类: B1_JAVA 2015-02-10 21:07 153人阅读 评论(0) 收藏

    简单来说,unicode,gbk和大五码就是编码的值,而utf-8,uft-16之类就是这个值的表现形式.而前面那三种编码是一兼容的,同一个汉字,那三个码值是完全不一样的.如"汉"的uncode值与g ...

  9. Ubuntu 字体修改以及字体的相关知识 分类: ubuntu 2014-06-19 21:46 81人阅读 评论(0) 收藏

    Ubuntu chrome 字体修改 打开任意一张含有输入框的网页,比如Google首页,然后右键点击"搜索框"会拉出一个菜单,我们这样选: 拼音检查选项==>语言设置==& ...

随机推荐

  1. Material UI:很强大的CSS框架

    Material UI 是一款功能很强大,界面却十分清新简洁的CSS框架.Material UI利用了Google的Material Design 全新设计语言.而且让每个UI组件都变得很独立.因此开 ...

  2. 微信小程序 自定义组件(modal) 引入组件

    项目结构: 步骤一:创建组件 声明这一组文件为自定义组件 modal.json { "component": true, // 自定义组件声明 "usingCompone ...

  3. 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用

    责任链模式的具体应用   1.业务场景 生产车间中使用的条码扫描,往往一把扫描枪需要扫描不同的条码来处理不同的业务逻辑,比如,扫描投入料工位条码.扫描投入料条码.扫描产出工装条码等,每种类型的条码位数 ...

  4. hdu4941 Magical Forest

    Problem Description There is a forest can be seen as N * M grid. In this forest, there is some magic ...

  5. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) D.Dinner Bet 概率DP+排列组合

    题目链接:点这里 题意: 1~N标号的球 现在A有C个,B有C个 每次可以随机得到D个不同的球(1~N);问你A或B中的C个球都出现一次的 期望次数 题解: dp[i][j][k]表示 随机出现了i个 ...

  6. Filter 详解

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  7. Latex 3: 解决LaTeX编译卡顿问题

    1.问题: 最近在编译latex时,老是在tulmr.fd处编译很久,但是以前不这样啊,那肯定就是我最近做了什么导致这样的了,是什么呢? 2.解决: 后来google下发现了解决办法,原来是我新安装了 ...

  8. HDU1045 Fire Net —— 二分图最大匹配

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045 Fire Net Time Limit: 2000/1000 MS (Java/Others)  ...

  9. android NDK 使用(多个)静态库生成动态库

    android NDK 使用(多个)静态库生成动态库. 1.编写Android.mk文件:如下两种方式都可以,用于NDK编译工具生成的两个.a文件来生成最终的libtwolib-second.so动态 ...

  10. Javaweb项目中文乱码

    Javaweb项目中文乱码 一.了解常识: 1.UTF-8国际编码,GBK中文编码.GBK包含GB2312,即如果通过GB2312编码后可以通过GBK解码,反之可能不成立; 2.web tomcat: ...