5.6.4 不得不说的问题

Base64算法一点都不复杂,但在Java API的文档中,我们看不到任何有关Base64算法的影子。但是,作者和广大读者朋友一样,坚信Sun公司一定会提供相应的Base64算法实现。

在sun.misc包中有两个类,BASE64Encoder类和BASE64Decoder类。BASE64Encoder类用于Base64编码,BASE64Decoder类用于Base64解码。但作者坚决反对使用这些Base64算法的实现类。

1.Base64算法的非标准实现

BASE64Encoder类继承于CharacterEncoder类,用于Base64编码:


//用于Base64编码。

public class BASE64Encoder

extends CharacterEncoder


BASE64Encoder类有一个最常用的方法:


//获得给定字节数组的Base64编码字符串。

public String encodeBuffer(byte b[])


与BASE64Encoder类相对应,BASE64Decoder类继承于CharacterDecoder类,用于Base64解码:


//用于Base64解码。

public class BASE64Decoder

extends CharacterDecoder


BASE64Decoder类有一个最常用的方法:


//获得给定的字符串的Base64解码字节数组。

public byte[]decodeBuffer(String s)


我们通过代码清单5-5展示如何使用Sun提供的Base64算法实现。

代码清单5-5 Base64算法Sun实现


import static org.junit.Assert.*;

import org.junit.Test;

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

/**

*Base64编码与解码测试类

*@author梁栋

*@version 1.0

*@since 1.0

*/

public class Base64CoderTest{

//测试Base64编码与解码

@Test

public final void test()throws Exception{

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

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

byte[]input=str.getBytes();

//Base64编码

BASE64Encoder encoder=new BASE64Encoder();

String data=encoder.encodeBuffer(input);

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

//Base64解码

BASE64Decoder decoder=new BASE64Decoder();

byte[]output=decoder.decodeBuffer(data);

System.err.println("解码后:\n\t"+new String(output));

}

}


以下为上述测试代码的输出结果:


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

编码后:SmF2YeWKoOWvhuS4juino+WvhueahOiJuuacrw==

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


注意上述输出结果,经Base64编码后的字符串有一个回车换行符(“\r\n”)。

注意观察图5-5中字符串变量code的值。

figure_0159_0032

图 5-5 Base64 Debug 4

2.非标准实现的问题

sun. misc包是Sun公司提供给内部使用的专用API,在编译上述代码时,尤其是使用Ant工具编译代码时,很可能获得以下提示内容:

警告:sun.misc.BASE64Decoder是Sun的专用API,可能会在未来版本中删除


import sun.misc.BASE64Decoder;

^


警告:sun.misc.BASE64Encoder是Sun的专用API,可能会在未来版本中删除


import sun.misc.BASE64Encoder;

^


在JRE中,以sun和com.sun开头的包的类都是未被文档化的,它们属于Java和Javax类库的基础,其中的实现大多数与底层平台有关,是不推荐使用的。

从实用角度来讲,我们不能直接使用JDK中以sun开头的包。因为,这是非标准的做法,将带来安全隐患!很有可能如编译器所提示的警告:“Sun的专用API,可能会在未来版本中删除”!

如何避免这种问题的出现呢?除了有意识地杜绝使用JDK API以外的JDK底层实现外,我们可以通过Eclipse设置来及时提醒,甚至中止编译。

在Eclipse中设置项目的JRE,如图5-6所示。

figure_0159_0033

图 5-6 在Eclipse中设置项目的JRE

选择JavaSE-1.6(jdk),在编译代码时如果引入了非标准的类库,就会有警告,并且不能完成编译,如图5-7所示。

figure_0160_0034

图 5-7 在Eclipse中使用非标准类库

正因为Sun提供的Base64算法实现是不推荐使用的,才会有Bouncy Castle和Commons Codec提供相应的解决方案。

作者强烈建议读者朋友(尤其是架构师们),按照标准路线构建应用,避免使用非标准实现,规避潜在风险!

综上所述,如果要使用Base64算法实现,那么Apache的Common Codec是我们最好的选择!