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码表

代码:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  5. int findindex(char c)
  6. {
  7. for(int i=0;i<64;i++)
  8. {
  9. if(c==table[i])
  10. return i;
  11. }
  12. return -1;
  13. }
  14. void base64enc(const char*src,char*&dst)
  15. {
  16. int slen=strlen(src);
  17. int len=slen;
  18. if(len%3!=0)len=(len/3+1)*3;//长度凑成3的倍数
  19. unsigned char*s=(unsigned char*)malloc(len*sizeof(unsigned char));//此处使用unsigned char,否则无法处理中文输入
  20. memset(s,0,len);
  21. memcpy(s,src,slen);
  22. int dlen=(len/3)*4+1;
  23. dst=(char*)malloc(dlen*sizeof(char));
  24. for(int i=0,j=0;i<len;i+=3)
  25. {
  26. //核心步骤
  27. //**************************************
  28. dst[j]=table[s[i]>>2];
  29. dst[j+1]=table[((s[i]&0X03)<<4)|(s[i+1]>>4)];
  30. dst[j+2]=table[((s[i+1]&0X0F)<<2)|(s[i+2]>>6)];
  31. dst[j+3]=table[s[i+2]&0X3F];
  32. //**************************************
  33. j+=4;
  34. }
  35. free(s);
  36. if(slen%3==1)dst[dlen-2]=dst[dlen-3]='=';
  37. if(slen%3==2)dst[dlen-2]='=';
  38. dst[dlen-1]=0;
  39. }
  40.  
  41. void base64dec(const char*src,char*&dst)
  42. {
  43. int slen=strlen(src);
  44. if(slen%4!=0)return ;
  45. int dlen=(slen/4)*3+1;
  46. char*d=(char*)malloc(dlen*sizeof(char));
  47. int index[4];
  48. for(int i=0,j=0;i<slen;i+=4)
  49. {
  50. for(int k=0;k<4;k++)
  51. {
  52. index[k]=findindex(src[i+k]);
  53. }
  54. //核心步骤
  55. //**************************************
  56. d[j]=index[0]<<2|index[1]>>4;
  57. d[j+1]=index[1]<<4|index[2]>>2;
  58. d[j+2]=index[2]<<6|index[3];
  59. //**************************************
  60. j+=3;
  61. }
  62. //去除src尾部'='的影响
  63. if(src[slen-1]=='='&&src[slen]!='=')
  64. dlen-=1;
  65. if(src[slen-1]=='='&&src[slen]=='=')
  66. dlen-=2;
  67. dst=(char*)malloc(dlen*sizeof(char));
  68. memcpy(dst,d,dlen);
  69. free(d);
  70. dst[dlen-1]=0;
  71. }
  72. int main()
  73. {
  74. char src[]="Hello,小罗";
  75. char*enc,*dec;
  76. base64enc(src,enc);
  77. base64dec(enc,dec);
  78. printf("%s\n",src);
  79. printf("%s\n",enc);
  80. printf("%s\n",dec);
  81. free(enc);
  82. free(dec);
  83. return 0;
  84. }

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

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. 【转】 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    原文:http://blog.csdn.net/testcs_dn/article/details/38496107 ----------------------------------------- ...

  2. sudo 用户添加

    sudo 用户添加 /etc/sudoers 在 ## Allow root to run any commands anywhere root    ALL=(ALL)   ALL 下面加上 xxx ...

  3. CentOS 7下安装Logstash ELK Stack 日志管理系统(下)

    修改防火墙,对外开放tcp/5601 [root@elk elk]# firewall-cmd --permanent --add-port=5601/tcpSuccess[root@elk elk] ...

  4. Firefox下td用display控制页面导致页面变形

    Firefox下table的td元素假设使用了display:'block'会使得table变形.原因是block会将对象强制作为块对象呈递,为对象之后加入新行,所以并不适合td,改成display: ...

  5. Android Activity与远程Service的通信学习总结

    当一个Service在androidManifest中被声明为 process=":remote", 或者是还有一个应用程序中的Service时,即为远程Service, 远程的意 ...

  6. 【Sublime】Sublime Text 2集成TortoiseSVN插件

    作者:zhanhailiang 日期:2014-09-30 1. 下载TortoiseSVN.将其安装在默认位置: 2. 使用Sublime包管理器下载安装TortoiseSVN Plugin,安装后 ...

  7. PHP 画图——使用jpgraph画图

     1.要支持中文须要用到simhei.ttf和simsun.ttc这两个字体,在使用中文的时候须要使用SetFont(FF_SIMSUN,FS_BOLD)设置字体. 将须要的字体放入到项目文件夹下 ...

  8. 3.2.1 配置构建Angular应用——简单的笔记存储应用——展示功能

    本节我们会通过构建一个简单的笔记存储应用(可以载入并修改一组简单的笔记)来学习如何应用Angular的特性.这个应用用到的特性有: 在JSON文件中存储笔记 展示.创建.修改和删除笔记 在笔记中使用M ...

  9. Memory Analysis环境安装

    安装MAT(MAT在eclipse的页面:http://www.eclipse.org/mat/downloads.php) 显示饼图的时候,需要安装BIRT Chart Engine插件,通过Ins ...

  10. su 和 su- 会影响环境变量

    大部分Linux发行版的默认账户是普通用户,而更改系统文件或者执行某些命令,需要root身份才能进行,这就需要从当前用户切换到root用户,Linux中切换用户的命令是su或su -,下面就su命令和 ...