[Java]Base64编码详解(附byte ←→hexString)

原创 2011年01月14日 10:42:00

什么是Base64?


按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列 的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)

Base64有个特征就是编码后的字符串长度为4的倍数。

 

算法详解


    Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。



可以这么考虑:把8位的字节连成一串110101011100010100110011
然后每次顺序选6个出来之后再把这6二进制数前面再添加两个0,就成了一个新的字节。之后再选出6个来,再添加0,依此类推,直到24个二进制数全部被选完。
让我们来看看实际结果:



这样“张3 ”这个字符串就被Base64表示为”5^/^T3”了么?。错!
Base64编码方式并不是单纯利用转化完的内容进行编码。像’^/’字符是控制字符,并不能通过计算机显示出来,在某些场合就不能使用了。Base64有其自身的编码表:



这 也是Base64名称的由来,而Base64编码的结果不是根据算法把编码变为高两位是0而低6为代表数据,而是变为了上表的形式,如”A”就有7位, 而”a”就只有6位。表中,编码的编号对应的是得出的新字节的十进制值。因此,从表2可以得到对应的Base64编码:



这样,字符串“张3”经过编码后就成了字符串“1iUz”了。
Base64将3个字节转变为4个字节,因此,编码后的代码量(以字节为单位,下同)约比编码前的代码量多了1/3。之所以说是“约”,是因为如果代码量正好是3的整数倍,那么自然是多了1/3。但如果不是呢?
细心的人可能已经注意到了,在The Base64 Alphabet中的最后一个有一个(pad) =字符。这个字符的目的就是用来处理这个问题的。
当代码量不是3的整数倍时,代码量/3的余数自然就是2或者1。转换的时候,结果不够6位的用0来补上相应的位置,之后再在6位的前面补两个0。转换完空出的结果就用就用“=”来补位。譬如结果若最后余下的为2个字节的“张”:



这样,最后的2个字节被整理成了“1iU=”。
同理,若原代码只剩下一个字节,那么将会添加两个“=”。只有这两种情况,所以,Base64的编码最多会在编码结尾有两个“=”
至于将Base64的解码,只是一个简单的编码的逆过程,读者可以自己探讨。我将在文章的最后给出解码算法。

 

自定义编码表


Base64推荐的编码表是为了达到比较好的可视效果,采用大小写的英文字母及10个数字和三个字符。在不考虑编码后可阅读性时,改变编码表,可以达到更加好的隐密效果。

byte的无符号数值范围为0~127,这决定了encodingTable中任一数据的赋值范围为0~127,并且数据与所赋值必须保留一一映射关系,而decodingTable的数组长度为128,decodingTable的序号与值相对应的是encodingTable的值与序号。

所以自定义编码表就是:对encodingTable的数据随机赋值为0~127的数并处理好该表与decodingTable的对应关系即可。在文章最后给出的代码就是一使用打乱字符顺序的编码表。

算法实现

其实在算法详解的时候基本上已经说的很清楚了。用于程序上,除去约束判断,大概可以分为如下几步几步:
读取数据3字节用AND取前6位,放入新的变量中右移两位,高两位清0AND取第一个字节的后2位和第二个字节的前4位移位放入新变量中右移两位,清0……依此类推。
编/解码的类Java语言实现的算法:

 

附byte与hexString的互转方式:

 

Base64是用4个字节表示3个字节的内容,HexString是2个字节表示1个字节的内容。

 

 

本文内容归CSDN博客博主Sodino 所有

转载请注明出处: http://blog.csdn.net/sodino/archive/2011/01/14/6137761.aspx

Java如何进行Base64的编码(Encode)与解码(Decode)?

Java进行Base64的编码(Encode)与解码(Decode)的几种方式与区别..
  • zhou_kapenter
  • zhou_kapenter
  • 2017年03月17日 16:37
  • 23621

java:7种Base64编码和解码功能详解和性能比较

Java 8新特性探究(十一)Base64详解 BASE64 编码是一种常用的字符编码,在很多地方都会用到。但base64不是安全领域下的加密解密算法。能起到安全作用的效果很差,而且很容...
  • u013476542
  • u013476542
  • 2016年11月18日 10:49
  • 12064

Java常用工具类封装——Base64 编码和解码

Base64 编码和解码工具类,供参考。 import java.io.*; /** * Base64 编码和解码。 * * @author jiangshuai * @date 2016年10月...
  • Dove_Knowledge
  • Dove_Knowledge
  • 2017年05月01日 11:23
  • 3119

Base64编码原理解析与Java实现

20180202更新:简化前言,重新排版。使用MARKDOWN排版:新版链接 一、前言 碰巧在慕课看到一个关于Base64的课程《Java实现Base64加密》,发现介绍了3个AP...
  • zdqdj1
  • zdqdj1
  • 2016年06月26日 00:39
  • 2646

BASE64编码规则及JAVA中的使用

一、编码规则:Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 例如字符串“张3” :11010101 110...
  • zzyy00
  • zzyy00
  • 2006年09月06日 22:40
  • 7480

Java 8实现BASE64编解码

Java 8实现BASE64编解码作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszsJava一直缺少BASE64编码 API,以至于通常在项目开发中会选用第三...
  • chszs
  • chszs
  • 2013年11月29日 17:27
  • 39132

Java中使用Base64编码实例

Maven需要引入的jar commons-codec commons-codec 1.10 org.bouncycastle bcprov-jdk15on 1.52 代码 packa...
  • lyliyongblue
  • lyliyongblue
  • 2015年09月08日 11:52
  • 1477

java 中使用base64编码和解码:

java 中使用base64编码和解码:   第一种方式: 通过反射使用java 中不对外公开的类: Java代码   /***       * encode by Base64   ...
  • QMW19910301
  • QMW19910301
  • 2015年10月15日 15:28
  • 1082

java用base64解密时,部分中文乱码原因

js中base64加密字符串,传到java后台后有些中文始终乱码 原因:js加密后,提交到后台,加密字符串中的“+”号,莫名其妙变成了空格!!尴尬 解决办法: 1、将空格替换成"+"; 2、将所有的...
  • hgg923
  • hgg923
  • 2017年06月01日 17:09
  • 2066

java实现base64编码和解码

编码规则:1、将3个字节转为4个字节,即每6个字节一组,高位补0                    2、原字节长度不是3的整数倍,结果串末尾使用=号补齐 以下是使用java代码的是实现 publi...
  • wzl19870309
  • wzl19870309
  • 2016年05月11日 11:08
  • 928
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[Java]Base64编码详解(附byte ←→hexString)
举报原因:
原因补充:

(最多只允许输入30个字)