一. Base64编码由来

  为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就 不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情 况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64就是一种 基于64个可打印字符来表示二进制数据的表示方法。

  二. Base64编码原理

  看一下Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符。数值代表字符的索引,这个是标准Base64协议规定的,不能更改。64个字符用6个bit位就可以全部表示,一个字节有8个bit 位,剩下两个bit就浪费掉了,这样就不得不牺牲一部分空间了。这里需要弄明白的就是一个Base64字符是8个bit,但是有效部分只有右边的6个 bit,左边两个永远是0。

  那么怎么用6个有效bit来表示传统字符的8个bit呢?8和6的最小公倍数 是24,也就是说3个传统字节可以由4个Base64字符来表示,保证有效位数是一样的,这样就多了1/3的字节数来弥补Base64只有6个有效bit 的不足。你也可以说用两个Base64字符也能表示一个传统字符,但是采用最小公倍数的方案其实是最减少浪费的。结合下边的图比较容易理解。Man是三个 字符,一共24个有效bit,只好用4个Base64字符来凑齐24个有效位。红框表示的是对应的Base64,6个有效位转化成相应的索引值再对应 Base64字符表,查出"Man"对应的Base64字符是"TWFU"。说到这里有个原则不知道你发现了没有,要转换成Base64的最小单位就是三个字节,对一个字符串来说每次都是三个字节三个字节的转换,对应的是Base64的四个字节。这个搞清楚了其实就差不多了。

         

  但是转换到最后你发现不够三个字节了怎么办呢?愿望终于实现了,我们可以用两 个Base64来表示一个字符或用三个Base64表示两个字符,像下图的A对应的第二个Base64的二进制位只有两个,把后边的四个补0就是了。所以 A对应的Base64字符就是QQ。上边已经说过了,原则是Base64字符的最小单位是四个字符一组,那这才两个字 符,后边补两个"="吧。其实不用"="也不耽误解码,之所以用"=",可能是考虑到多段编码后的Base64字符串拼起来也不会引起混淆。由此可见 Base64字符串只可能最后出现一个或两个"=",中间是不可能出现"="的。下图中字符"BC"的编码过程也是一样的。

三:base64的三种实现方式:

方式一:jdk方式实现

// 用jdk实现public static void jdkBase64(){try {BASE64Encoder encoder = new BASE64Encoder();String encode = encoder.encode(src.getBytes());System.out.println("encode:" + encode);BASE64Decoder decoder = new BASE64Decoder();System.out.println("decode:" + new String(decoder.decodeBuffer(encode)));} catch (Exception e) {e.printStackTrace();}}

方式二:用Apache的common codes实现

// 用Apache的common codes实现public static void commonsCodesBase64(){byte[] encodeBytes = Base64.encodeBase64(src.getBytes());System.out.println("common codes encode:" + new String(encodeBytes));byte[] dencodeBytes = Base64.decodeBase64(encodeBytes);System.out.println("common codes decode:" + new String(dencodeBytes));}

方式三:用bouncy castle实现

// 用bouncy castle实现public static void bouncyCastleBase64(){byte[] encodeBytes = org.bouncycastle.util.encoders.Base64.encode(src.getBytes());System.out.println("bouncy castle encode:" + new String(encodeBytes));byte[] dencodeBytes = org.bouncycastle.util.encoders.Base64.decode(encodeBytes);System.out.println("bouncy castle decode:" + new String(dencodeBytes));}

总结  

  说起Base64编码可能有些奇怪,因为大多数的编码都是由字符转化成二进制的过程,而从二进制转成字符的过程称为解码。而Base64的概念就恰好反了,由二进制转到字符称为编码,由字符到二进制称为解码。

  Base64编码主要用在传输、存储、表示二进制等领域,还可以用来加密,但是这种加密比较简单,只是一眼看上去不知道什么内容罢了,当然也可以对Base64的字符序列进行定制来进行加密。

  Base64编码是从二进制到字符的过程,像一些中文字符用不同的编码转为二 进制时,产生的二进制是不一样的,所以最终产生的Base64字符也不一样。例如"上网"对应utf-8格式的Base64编码是"5LiK572R", 对应GB2312格式的Base64编码是"yc/N+A=="。

好了,已经理解了什么是base64,相信大家最关心的还是base64的实现方式,下面我就对base64的3中实现方式一一实现给出具体的代码实现:

java_security之base64原理解析以及三种代码的实现方式相关推荐

  1. JSON数据解析的三种情况+pjson的方式

    直接解析JavaScript中的json字符串 <!-- 解析页面内的字符串 --> <div align="center"><table class ...

  2. SSO单点登录三种情况的实现方式详解

    SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...

  3. (转)Spring的三种实例化Bean的方式

    http://blog.csdn.net/yerenyuan_pku/article/details/52832793 Spring提供了三种实例化Bean的方式. 使用类构造器实例化. <be ...

  4. SpringBoot 三种拦截http请求方式Filter,interceptor和aop

    SpringBoot 三种拦截http请求方式Filter,interceptor和aop. 这三种拦截方式的拦截顺序是:filter->Interceptor-->ControllerA ...

  5. zynq学习03 zynq中三种实现GPIO的方式

    http://m.blog.csdn.net/article/details?id=52123465 http://blog.chinaaet.com/songhuangong/p/43084 本文介 ...

  6. Objective-C:三种文件导入的方式以及atomic和nonatomic的区别

    一.三种文件导入的方式比较:   类的前项声明@class.import.include: 1.采用@class 类名的方式,它会告诉编译器有这么一个类,目前不需要知道它内部的实例变量和方法是如何定义 ...

  7. 浅淡Webservice、WSDL三种服务访问的方式(附案例)

    Webservice Webservice是使应用程序以与平台和编程语言无关的方式进行相互通信技术. eg:站点提供访问的数据接口:新浪微博.淘宝. 官方解释:它是一种构建应用程序的普遍模型,可以在任 ...

  8. Python中的urllib,urllib三种不同的请求方式

    1.urllib获取服务器的资源 自定义爬虫的重要组件 获取百度首页的资源: #3.x的标准写法 import urllib.request import urllib.parse#百度的首页 fro ...

  9. JAVA 三种线程实现创建方式

    JAVA 三种线程实现/创建方式 方式一:继承Thread类 通过继承Thread类来创建一个自定义线程类.Thread类本质上就继承了Runable接口,代表一个线程类.启动线程的唯一办法就是通过T ...

最新文章

  1. Linux 的多线程编程的高效开发经验
  2. ubutnu16.04搭建LAMP环境(搭建wordpress博客)
  3. WLAN高密无线网络部署的信道问题
  4. SAP Fiori应用里日期格式的显示奥秘
  5. java 上传文件编码_(java)有什么办法把MultipartFile上传的文件转为utf-8的编码吗
  6. ios把数据传递到另一个页面_IOS 应用之间的跳转和数据传递详解
  7. 关于html标签元素的data-*属性
  8. linux git ssh_Git年满13岁,可以了解Linux和SSH命令,Python编程等等
  9. SpringBoot 阶段总结
  10. Exchange 日志/存储路径
  11. 当下流行的语音识别技术是不是发展错了方向?
  12. Kontakt 6 for Mac(强大的音频采样器软件)
  13. CC***的解决方案
  14. 开发技巧 | Python极简实现滑动平均滤波(基于Numpy.convolve)
  15. Jmeter二次开发实现rsa加密
  16. error: crosses initialization of
  17. 【产品经理】003-梁宁·产品思维30讲-机会判断(未完待续)
  18. SQL Server 2008 中文企业版下载
  19. Ubuntu18.04安装灭霸SLAM:ORBSLAM3
  20. C# 添加Word页眉、页脚和页码

热门文章

  1. 面试造飞机,工作拧螺丝。
  2. Databricks文档03----Azure Databricks 创建
  3. Python3 爬虫(一)-- 简单网页抓取
  4. 投资大佬段永平:抄底腾讯,不等了!
  5. 一加手机史上超大购机优惠 以旧换新至高补贴3800元
  6. 格力电器成为银隆新能源股东 持股30.47%
  7. 供应商禁止供货后,这个城市行动了:社区团购不得低价倾销、排挤对手
  8. 华为高管预告手机鸿蒙OS下月上线,华为手机部:我们没说过
  9. “常程跳槽小米”裁决出炉:常程继续履行竞业限制,还要赔500多万...
  10. 10月23日见?疑似魅族16T预热海报曝光:定位大屏娱乐旗舰