這篇文章主要為大家詳細介紹了Java8新特性之Base64的相關資料,具有一定的參考價值,有興趣的小伙伴們可以參考一下
BASE64 編碼是一種常用的字符編碼,很多地方都會用到。但base64不是安全領域下的加密解密演算法。能起到安全作用的效果很差,而且很容易破解,他核心作用應該是傳輸資料的正確性,有些網關或系統只能使用ASCII字元。 Base64就是用來將非ASCII字元的資料轉換成ASCII字元的一種方法,而且base64特別適合在http,mime協定下快速傳輸資料。
JDK裡面實作Base64的API
在JDK1.6之前,JDK核心類別一直沒有Base64的實作類,有人建議用Sun /Oracle JDK裡面的sun.misc.BASE64Encoder 和sun.misc.BASE64Decoder,使用它們的優點就是不需要依賴第三方類別庫,缺點就是可能在未來版本會被刪除(用maven編譯會發出警告),而且性能不佳,後面會有性能測試。
JDK1.6中加入了另一個Base64的實現,javax.xml.bind.DatatypeConverter兩個靜態方法parseBase64Binary 和printBase64Binary,隱藏在javax.xml.bind套件下面,不被很多開發者知道。
在Java 8在java.util套件下面實作了BASE64編解碼API,而且效能不俗,API也簡單易懂,下面展示下這個類別的使用範例。
java.util.Base64
#該類別提供了一套靜態方法來取得下面三種BASE64編解碼器:
1)Basic編碼:是標準的BASE64編碼,用於處理常規的需求
// 编码 String asB64 = Base64.getEncoder().encodeToString("some string".getBytes("utf-8")); System.out.println(asB64); // 输出为: c29tZSBzdHJpbmc= // 解码 byte[] asBytes = Base64.getDecoder().decode("c29tZSBzdHJpbmc="); System.out.println(new String(asBytes, "utf-8")); // 输出为: some string
2)URL編碼:使用底線替換URL裡面的反斜線「/」
String urlEncoded = Base64.getUrlEncoder().encodeToString("subjects?abcd".getBytes("utf-8")); System.out.println("Using URL Alphabet: " + urlEncoded); // 输出为: Using URL Alphabet: c3ViamVjdHM_YWJjZA==
3)MIME編碼:使用基本的字母數字產生BASE64輸出,而且對MIME格式友善:每一行輸出不超過76個字符,而且每行以“\r\n”符結束。
StringBuilder sb = new StringBuilder(); for (int t = 0; t < 10; ++t) { sb.append(UUID.randomUUID().toString()); } byte[] toEncode = sb.toString().getBytes("utf-8"); String mimeEncoded = Base64.getMimeEncoder().encodeToString(toEncode); System.out.println(mimeEncoded);
第三方實作Base64的API
首先是常用的Apache Commons Codec library裡面的org.apache.commons.codec.binary.Base64;
第二個便是Google Guava庫裡面的com.google.common.io.BaseEncoding.base64() 這個靜態方法;
第三個是net.iharder.Base64,這個jar包就一個類;
最後一個,號稱Base64編碼速度最快的MigBase64,而且是10年前的實現,到現在是否能保持這個稱號,測一測便知道;
Base64編碼效能測試
上面講了一共7種實作Base64編碼,Jdk裡面3種,第三方實作4種,一旦有選擇,則有必要將他們進行一次高低對比,性能測試是最直接的方式
首先來定義兩個接口
private static interface Base64Codec { public String encode(final byte[] data); public byte[] decode(final String base64) throws IOException; } private static interface Base64ByteCodec { public byte[] encodeBytes(final byte[] data); public byte[] decodeBytes(final byte[] base64) throws IOException; }
兩個介面差異就是其中一個介面方法參數接收byte數組,回傳byte數組,因為byte->byte比起String->byte或byte->String效能上會快一點,所以區分兩組來測試
private static final Base64Codec[] m_codecs = { new GuavaImpl(), new JavaXmlImpl(), new Java8Impl(), new SunImpl(), new ApacheImpl(),new MiGBase64Impl(),new IHarderImpl() }; private static final Base64ByteCodec[] m_byteCodecs = { new ApacheImpl(), new Java8Impl(),new MiGBase64Impl(),new IHarderImpl() };
從上面看出,其中支援byte->byte只有4中API;
7個Base64的實作類別
private static class Java8Impl implements Base64Codec, Base64ByteCodec { private final Base64.Decoder m_decoder = Base64.getDecoder(); private final Base64.Encoder m_encoder = Base64.getEncoder(); @Override public String encode(byte[] data) { return m_encoder.encodeToString(data); } @Override public byte[] decode(String base64) throws IOException { return m_decoder.decode(base64); } public byte[] encodeBytes(byte[] data) { return m_encoder.encode( data ); } public byte[] decodeBytes(byte[] base64) throws IOException { return m_decoder.decode( base64 ); } } private static class JavaXmlImpl implements Base64Codec //no byte[] implementation { public String encode(byte[] data) { return DatatypeConverter.printBase64Binary( data ); } public byte[] decode(String base64) throws IOException { return DatatypeConverter.parseBase64Binary( base64 ); } } ..............
後面程式碼基本上就是各種API實作Base64的程式碼了,就不詳細列出。
主要測試手段是,產生100M的隨機數,分成100byte或1000byte的區塊,然後將他們分別編碼和解碼,記錄時間,如下方法
private static TestResult testByteCodec( final Base64ByteCodec codec, final List<byte[]> buffers ) throws IOException { final List<byte[]> encoded = new ArrayList<byte[]>( buffers.size() ); final long start = System.currentTimeMillis(); for ( final byte[] buf : buffers ) encoded.add( codec.encodeBytes(buf) ); final long encodeTime = System.currentTimeMillis() - start; final List<byte[]> result = new ArrayList<byte[]>( buffers.size() ); final long start2 = System.currentTimeMillis(); for ( final byte[] ar : encoded ) result.add( codec.decodeBytes(ar) ); final long decodeTime = System.currentTimeMillis() - start2; for ( int i = 0; i < buffers.size(); ++i ) { if ( !Arrays.equals( buffers.get( i ), result.get( i ) ) ) System.out.println( "Diff at pos = " + i ); } return new TestResult( encodeTime / 1000.0, decodeTime / 1000.0 ); }
測試結果
jvm參數:-Xms512m -Xmx4G
#一切都很明顯了,從上面看出,sun的表現不是很好,IHarder和MigBase64性能可以接受,傳說MigBase64性能第一,那也是過去了,在這次測試結果中,新的java8 base64運行速度最好, javaXml表現次之。
總結
如果你需要一個效能好,可靠的Base64編解碼器,不要找JDK外面的了,java8裡面的java .util.Base64以及java6隱藏很深的javax.xml.bind.DatatypeConverter,他們兩個都是不錯的選擇。
以上是解讀Java8新功能--Base64的詳細內容。更多資訊請關注PHP中文網其他相關文章!