Java8新特性之Base64詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
BASE64 編碼是一種常用的字符編碼,在很多地方都會(huì)用到。但base64不是安全領(lǐng)域下的加密解密算法。能起到安全作用的效果很差,而且很容易破解,他核心作用應(yīng)該是傳輸數(shù)據(jù)的正確性,有些網(wǎng)關(guān)或系統(tǒng)只能使用ASCII字符。Base64就是用來將非ASCII字符的數(shù)據(jù)轉(zhuǎn)換成ASCII字符的一種方法,而且base64特別適合在http,mime協(xié)議下快速傳輸數(shù)據(jù)。
JDK里面實(shí)現(xiàn)Base64的API
在JDK1.6之前,JDK核心類一直沒有Base64的實(shí)現(xiàn)類,有人建議用Sun/Oracle JDK里面的sun.misc.BASE64Encoder 和 sun.misc.BASE64Decoder,使用它們的優(yōu)點(diǎn)就是不需要依賴第三方類庫,缺點(diǎn)就是可能在未來版本會(huì)被刪除(用maven編譯會(huì)發(fā)出警告),而且性能不佳,后面會(huì)有性能測試。
JDK1.6中添加了另一個(gè)Base64的實(shí)現(xiàn),javax.xml.bind.DatatypeConverter兩個(gè)靜態(tài)方法parseBase64Binary 和 printBase64Binary,隱藏在javax.xml.bind包下面,不被很多開發(fā)者知道。
在Java 8在java.util包下面實(shí)現(xiàn)了BASE64編解碼API,而且性能不俗,API也簡單易懂,下面展示下這個(gè)類的使用例子。
java.util.Base64
該類提供了一套靜態(tài)方法獲取下面三種BASE64編解碼器:
1)Basic編碼:是標(biāo)準(zhǔn)的BASE64編碼,用于處理常規(guī)的需求
// 編碼 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編碼:使用基本的字母數(shù)字產(chǎn)生BASE64輸出,而且對(duì)MIME格式友好:每一行輸出不超過76個(gè)字符,而且每行以“\r\n”符結(jié)束。
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);
第三方實(shí)現(xiàn)Base64的API
首先便是常用的Apache Commons Codec library里面的org.apache.commons.codec.binary.Base64;
第二個(gè)便是Google Guava庫里面的com.google.common.io.BaseEncoding.base64() 這個(gè)靜態(tài)方法;
第三個(gè)是net.iharder.Base64,這個(gè)jar包就一個(gè)類;
最后一個(gè),號(hào)稱Base64編碼速度最快的MigBase64,而且是10年前的實(shí)現(xiàn),到現(xiàn)在是否能保持這個(gè)稱號(hào),測一測便知道;
Base64編碼性能測試
上面講了一共7種實(shí)現(xiàn)Base64編碼,Jdk里面3種,第三方實(shí)現(xiàn)4種,一旦有選擇,則有必要將他們進(jìn)行一次高低對(duì)比,性能測試是最直接的方式
首先來定義兩個(gè)接口
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; }
兩個(gè)接口區(qū)別就是其中一個(gè)接口方法參數(shù)接收byte數(shù)組,返回byte數(shù)組,因?yàn)閎yte->byte相比String->byte或者byte->String性能上會(huì)快一點(diǎn),所以區(qū)分兩組來測試
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個(gè)Base64的實(shí)現(xiàn)類
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實(shí)現(xiàn)Base64的代碼了,就不詳細(xì)列出。
主要測試手段是,生成100M的隨機(jī)數(shù),分成100byte或者1000byte的塊,然后將他們分別編碼和解碼,記錄時(shí)間,如下方法
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 ); }
測試結(jié)果
jvm參數(shù):-Xms512m -Xmx4G
一切都很明顯了,從上面看出,sun的表現(xiàn)不是很好,IHarder和MigBase64性能可以接受,傳說MigBase64性能第一,那也是過去了,在這次測試結(jié)果中,新的java8 base64運(yùn)行速度最好,javaXml表現(xiàn)次之。
總結(jié)
如果你需要一個(gè)性能好,可靠的Base64編解碼器,不要找JDK外面的了,java8里面的java.util.Base64以及java6中隱藏很深的javax.xml.bind.DatatypeConverter,他們兩個(gè)都是不錯(cuò)的選擇。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- java8版本base64加密解密的實(shí)例
- Java基于Base64實(shí)現(xiàn)編碼解碼圖片文件
- 詳解Java如何進(jìn)行Base64的編碼(Encode)與解碼(Decode)
- Java處理圖片實(shí)現(xiàn)base64編碼轉(zhuǎn)換
- java將圖片轉(zhuǎn)為base64返回給前端
- 基于Java實(shí)現(xiàn)文件和base64字符串轉(zhuǎn)換
- java使用Base64實(shí)現(xiàn)文件加密解密
- java使用Base64編碼實(shí)例
- Java實(shí)現(xiàn)文件和base64流的相互轉(zhuǎn)換功能示例
- 詳細(xì)分析JAVA8新特性 Base64
相關(guān)文章
Java文件字符輸入流FileReader讀取txt文件亂碼的解決
這篇文章主要介紹了Java文件字符輸入流FileReader讀取txt文件亂碼的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09淺談springmvc 通過異常增強(qiáng)返回給客戶端統(tǒng)一格式
這篇文章主要介紹了淺談springmvc 通過異常增強(qiáng)返回給客戶端統(tǒng)一格式。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09把spring boot項(xiàng)目發(fā)布tomcat容器(包含發(fā)布到tomcat6的方法)
這篇文章主要介紹了把spring boot項(xiàng)目發(fā)布tomcat容器(包含發(fā)布到tomcat6的方法),然后在文章給大家提到了如何將Spring Boot項(xiàng)目打包部署到外部Tomcat,需要的朋友參考下吧2017-11-11idea?maven?經(jīng)常主目錄自動(dòng)變回默認(rèn)的解決方法
很多朋友反映idea?maven?經(jīng)常主目錄自動(dòng)變回默認(rèn),遇到這樣的問題真的很頭疼,該如何解決呢?下面小編給大家介紹下idea?maven目錄變回默認(rèn)的解決方法,需要的朋友可以參考下2022-08-08基于SpringBoot和Vue3的博客平臺(tái)文章詳情與評(píng)論功能實(shí)現(xiàn)
在前面的教程中,我們已經(jīng)實(shí)現(xiàn)了基于Spring Boot和Vue3的發(fā)布、編輯、刪除文章功能以及文章列表與分頁功能。本教程將引導(dǎo)您實(shí)現(xiàn)博客平臺(tái)的文章詳情與評(píng)論功能,需要的朋友可以參考一下2023-04-04SpringBoot中MockMVC單元測試的實(shí)現(xiàn)
Mock是一種用于模擬和替換類的對(duì)象的方法,以便在單元測試中獨(dú)立于外部資源進(jìn)行測試,本文主要介紹了SpringBoot中MockMVC單元測試的實(shí)現(xiàn),具有應(yīng)該的參考價(jià)值,感興趣的可以了解一下2024-02-02