5.6.2 Commons Codec
在开源组织中,尤其是Java开源组织中,Apache总能为我们提供各种便利的组件包,使我们的开发工作如虎添翼。Apache提供了用于编码转换的组件包Commons Codec,它遵循RFC 2045的相关定义,实现了Base64算法,同时也支持了一般Base64算法的实现。
Commons Codec中用于Base64算法的实现是Base64类,请读者朋友查看第4章相关内容。
我们不改变上一小节中对于Base64Coder类的方法定义,只替换对应方法中的代码实现,完成简单的Base64算法实现。
这里请读者朋友注意使用Base64类的静态方法encodeBase64(),它有多种方法重载,可根据参数决定是否执行RFC 2045标准。
如使用以下方法,将完成一般Base64编码:
//以字节数组返回Base64编码结果。
public static byte[]encodeBase64(byte[]binaryData)
如果使用以下方法,同时将参数isChunked置为true,将按RFC 2045标准执行:
/以字节数组形式返回Base64编码结果,对输出结果中每76个字符追加一个回车换行符。/
public static byte[]encodeBase64(byte[]binaryData, boolean isChunked)
接下来我们改用Commons Codec的Base64算法的相应实现,如代码清单5-3所示。
代码清单5-3 Base64组件2
import org.apache.commons.codec.binary.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.encodeBase64(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
/**
*Base64安全编码<br>
*遵循RFC 2045实现
*@param data待编码数据
*@return String编码数据
*@throws Exception
*/
public static String encodeSafe(String data)throws Exception{
//执行编码
byte[]b=Base64.encodeBase64(data.getBytes(ENCODING),true);
return new String(b, ENCODING);
}
/**
*Base64解码
*@param data待解码数据
*@return String解码数据
*@throws Exception
*/
public static String decode(String data)throws Exception{
//执行解码
byte[]b=Base64.decodeBase64(data.getBytes(ENCODING));
return new String(b, ENCODING);
}
}
这里对于编码操作实现了2个方法,一个方法用于一般Base64编码实现(encode()方法),另一个用于RFC 2045标准的Base64编码实现(encodeSafe()方法)。
对于解码操作,Commons Codec的Base64类仅需要同一个方法来处理,我们在这里对其包装构造了decode()方法。
对于上述算法实现,给出相应的测试用例,如代码清单5-4所示。
代码清单5-4 Base64组件2测试用例
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);
}
//测试Base64编码与解码
@Test
public final void testSafe()throws Exception{
String inputStr="Java加密与解密的艺术";
System.err.println("原文:\t"+inputStr);
//进行Base64编码
String code=Base64Coder.encodeSafe(inputStr);
System.err.println("编码后:\t"+code);
//进行Base64解码
String outputStr=Base64Coder.decode(code);
System.err.println("解码后:\t"+outputStr);
//验证Base64编码解码一致性
assertEquals(inputStr, outputStr);
}
}
我们分别执行两个测试方法。通过执行test()方法,在控制台中获得如下信息:
原文:Java加密与解密的艺术
编码后:SmF2YeWKoOWvhuS4juino+WvhueahOiJuuacrw==
解码后:Java加密与解密的艺术
观察Debug信息,如图5-3所示。
图 5-3 Base64 Debug 2
注意图中字符串变量code的值,我们确定Base64Coder类的encode()方法仅实现了一般Base64编码操作。
我们再来执行testSafe()方法,在控制台中获得如下信息:
原文:Java加密与解密的艺术
编码后:SmF2YeWKoOWvhuS4juino+WvhueahOiJuuacrw==
解码后:Java加密与解密的艺术
这里有个换行,我们很难断定是否还有回车换行符。通过图5-4,我们得到了验证。
注意图中字符串变量code的值,我们明显看到这里有一个回车换行符(“\r\n”)。我们确定Base64Coder类的encodeSafe()方法遵照RFC 2045定义实现了Base64编码操作。
图 5-4 Base64 Debug 3
注意 根据RFC 2045定义,每行为76个字符,行末加入一个回车换行符。但并不是当每行够了76个字符才需要在行末加入一个回车换行符,每行不管够不够76个字符都要加入一个回车换行符。