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编码后的字符串中的“+”和“=”符号分别替换为“-”和“.”符号,而且没有换行的概念。