Java 8新特性探究(五)Base64详解

本文介绍 Java8 中 Base64 的编解码方法,并通过性能测试比较 JDK 和第三方库的不同实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/jerome_s/article/details/45285685


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 8Java.util包下面实现了BASE64编解码API,而且性能不俗,API也简单易懂,下面展示下这个类的使用例子。

java.util.Base64

该类提供了一套静态方法获取下面三种BASE64编解码器:

1)Basic编码:是标准的BASE64编码,用于处理常规的需求

?

1

2

3

4

5

6

// 编码

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里面的反斜线“/”

?

1

2

3

4

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”符结束。

?

1

2

3

4

5

6

7

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种,一旦有选择,则有必要将他们进行一次高低对比,性能测试是最直接的方式

首先来定义两个接口

?

1

2

3

4

5

6

7

8

9

10

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性能上会快一点,所以区分两组来测试

?

1

2

3

4

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的实现类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

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的块,然后将他们分别编码和解码,记录时间,如下方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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,他们两个都是不错的选择。

from:http://my.oschina.NET/benhaile/blog/267738

还有很多Java8新特性比如:

OOM:Permgen说再见 元空间(MetaSpace)一种新的内存空间诞生

StampedLock将是解决同步问题的新宠

Nashorn :新犀牛 (java8新一代的JavaScript引擎

JavaFX 8新特性

参考:http://my.oschina.net/benhaile/blog?disp=1&catalog=410404&sort=time&p=1 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值