5.7 Url Base64算法实现

相信读者对于URL传递参数已经很熟悉了,如何通过HTTP请求传递URL参数似乎是一个很简单的问题,但问题往往出在非常时期。Get方式和Post方式是最为常用的两种HTTP请求方式,但如果要求使用Get方式传递本该由Post方式传递的私密数据时该怎么办?如果非要在Get方式下传递二进制数据怎么办?此时,使用Url Base64算法是一个不错的选择。

目前,对于Url Base64算法还没有一个明确的定义,我们所获得的最新的相关文档是RFC 4648,其中列举了关于Url Base64算法的构建建议。

Url Base64算法定义有别于RFC 2045,它不需要定义每行字符数及行末回车换行符。同时,根据URL相关要求,符号“+”和符号“/”是不允许出现在URL中的,RFC 4648中给出了相应的替代符号“-”和“_”。同样,符号“=”用做参数分隔符,也不允许出现在URL中。符号“=”在Base64算法中用做填充符,如果需要定长的Base64编码串,就需要有相应的替代符号。

根据RFC 4648中的建议,“~”和“.”符都有可能替代“=”符号。但“~”符号与文件系统相冲突,不能使用;如果使用“.”符号,某些文件系统认为该符号连续出现两次则为错误。正如本章前文所述,Base64编码后的字符串中,填充符可以重复出现,并且最多只能出现两次。如果使用“.”符号作为填充符,则与某些系统相冲突。

Bouncy Castle和Commons Codec都实现了Url Base64算法,不同的是,Bouncy Castle使用“.”作为填充符,而Commons Codec则直接放弃了填充符,使用不定长Url Base64编码。

5.7.1 Bouncy Castle

Bouncy Castle提供了Url Base64算法的实现类UrlBase64,它遵从了RFC 4648中的建议,使用“.”符号作为填充符,构建定长Url Base64编码,如代码清单5-6所示。

代码清单5-6 Url Base64处理1


import org.bouncycastle.util.encoders.UrlBase64;

/**

*Url Base64组件

*@author梁栋

*@version 1.0

*@since 1.0

*/

public abstract class UrlBase64Coder{

//字符编码

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

/**

*Url Base64编码

*@param data待编码数据

*@return String编码数据

*@throws Exception

*/

public static String encode(String data)throws Exception{

//执行编码

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

return new String(b, ENCODING);

}

/**

*Url Base64解码

*@param data待解码数据

*@return String解码数据

*@throws Exception

*/

public static String decode(String data)throws Exception{

//执行解码

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

return new String(b, ENCODING);

}

}


我们通过代码清单5-7来验证上述操作。

代码清单5-7 Url Base64处理1测试用例


import static org.junit.Assert.*;

import org.junit.Test;

/**

*Url Base64编码与解码测试类

*@author梁栋

*@version 1.0

*@since 1.0

*/

public class UrlBase64CoderTest{

//测试Base64编码与解码

@Test

public final void test()throws Exception{

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

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

//进行Base64编码

String code=UrlBase64Coder.encode(inputStr);

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

//进行Base64解码

String outputStr=UrlBase64Coder.decode(code);

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

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

assertEquals(inputStr, outputStr);

}

}


注意控制台输出信息:


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

编码后:SmF2YeWKoOWvhuS4juino-WvhueahOiJuuacrw..

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


我们使用Base64编码后得到的是以下信息:


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

编码后:SmF2YeWKoOWvhuS4juino+WvhueahOiJuuacrw==

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


对比差别,发现使用Base64编码后的字符串中的“+”和“=”符号分别替换为“-”和“.”符号,而且没有换行的概念。