5.6 Base64算法实现

对于Base64算法,在Java API文档中,我们看不到有关它的任何身影。其实这种算法并不复杂,我们通过手工都能完成编码解码的演算。但是,Sun公司依旧没有提供相应的实现。开源组织总是在必要的时候弥补Sun公司的缺陷,壮大Java的世界。Bouncy Castle和Commons Codec两大开源组件包,填补了Java 6缺失Base64算法实现的遗憾。但实际上Sun也做了Base64算法的实现,却不能将其公示,这令众多Java开发者倍感疑惑。

在Bouncy Castle和Commons Codec两大开源组件包中,Bouncy Castle提供了一般Base64算法的实现,而Commons Codec还提供了基于RFC 2045相关定义的Base64算法实现。

5.6.1 Bouncy Castle

Bouncy Castle遵循的是一般Base64算法,也就是简单地根据Base64字符映射表做了编码转换。对于本文开篇的那一段神奇的乱码转换,我们先通过Bouncy Castle来做一下实现分析。

Bouncy Castle的Base64类对于编码/解码操作只有简单的两个方法,请读者阅读第4章相关内容。

我们一起来看代码清单5-1,从而了解用于操作Base64算法的实现类Base64Coder。

代码清单5-1 Base64组件1


import org.bouncycastle.util.encoders.Base64;

/**

*Base64组件

*@author梁栋

*@version 1.0

*@since 1.0

*/

public abstract class Base64Coder{

//字符编码

public final static String ENCODING="UTF-8";

/**

*Base64编码

*@param data待编码数据

*@return String编码数据

*@throws Exception

*/

public static String encode(String data)throws Exception{

//执行编码

byte[]b=Base64.encode(data.getBytes(ENCODING));

return new String(b, ENCODING);

}

/**

*Base64解码

*@param data待解码数据

*@return String解码数据

*@throws Exception

*/

public static String decode(String data)throws Exception{

//执行解码

byte[]b=Base64.decode(data.getBytes(ENCODING));

return new String(b, ENCODING);

}

}


Base64算法实现起来就是这么简单,仅用几行代码就完成了编码/解码的调用实现。代码清单5-2是相应的测试用例代码。

代码清单5-2 Base64组件1测试用例


import static org.junit.Assert.*;

import org.junit.Test;

/**

*Base64编码与解码测试类

*@author梁栋

*@version 1.0

*@since 1.0

*/

public class Base64CoderTest{

//测试Base64编码与解码

@Test

public final void test()throws Exception{

String inputStr="Java加密与解密的艺术";

System.err.println("原文:\t"+inputStr);

//进行Base64编码

String code=Base64Coder.encode(inputStr);

System.err.println("编码后:\t"+code);

//进行Base64解码

String outputStr=Base64Coder.decode(code);

System.err.println("解码后:\t"+outputStr);

//验证Base64编码解码一致性

assertEquals(inputStr, outputStr);

}

}


我们终于在控制台中看到了如下信息:


原文:Java加密与解密的艺术

编码后:SmF2YeWKoOWvhuS4juino+WvhueahOiJuuacrw==

解码后:Java加密与解密的艺术


请大家注意,原文经Base64编码后,并没有多出一个回车换行符!请大家注意图5-2中,code变量的值并没有相应的回车换行符(“\r\n")。

figure_0153_0029

图 5-2 Base64 Debug 1

Bouncy Castle未能遵循RFC 2045的相关定义,但在实际使用中,有时候我们恰恰有意需要这么做。如果需要完全遵循RFC 2045,那就使用Commons Codec吧!