Home  >  Article  >  Java  >  Interpretation of new features of Java8--Base64

Interpretation of new features of Java8--Base64

零下一度
零下一度Original
2017-06-17 14:10:201836browse

This article mainly introduces the relevant information of Base64, a new feature of Java8, in detail. It has certain reference value. Interested friends can refer to it.

BASE64 encoding is a commonly used character. Coding is used in many places. But base64 is not an encryption and decryption algorithm in the security field. The security effect is very poor and it is easy to crack. Its core function should be the correctness of transmitted data. Some gateways or systems can only use ASCII characters. Base64 is a method used to convert non-ASCII character data into ASCII characters, and base64 is particularly suitable for fast data transmission under http and mime protocols.

The API to implement Base64 in JDK

Before JDK1.6, there was no Base64 implementation class in the JDK core classes. Some people suggested using Sun /Sun.misc.BASE64Encoder and sun.misc.BASE64Decoder in Oracle JDK. The advantage of using them is that they do not need to rely on third-party class libraries. The disadvantage is that they may be deleted in future versions (compiling with maven will cause Issue a warning), and the performance is not good, there will be performance testing later.

Another implementation of Base64 has been added to JDK1.6, two javax.xml.bind.DatatypeConverter static methods parseBase64Binary and printBase64Binary, hidden in the javax.xml.bind package Below, not known by many developers.

In Java 8, the BASE64 encoding and decoding API is implemented under the java.util package, and the performance is good, and the API is simple and easy to understand. Below is a usage example of this class.

java.util.Base64

This class provides a set of static methods to obtain the following three BASE64 codecs:

1) Basic encoding: It is a standard BASE64 encoding, used to handle regular requirements


// 编码
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 encoding: Use underscores to replace URLs The backslash "/" inside


String urlEncoded = Base64.getUrlEncoder().encodeToString("subjects?abcd".getBytes("utf-8"));
System.out.println("Using URL Alphabet: " + urlEncoded);
// 输出为:
Using URL Alphabet: c3ViamVjdHM_YWJjZA==

3) MIME encoding: uses basic alphanumeric to produce BASE64 output, and is friendly to the MIME format: output per line No more than 76 characters, and each line ends with the "\r\n" character.


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);

Third-party implementation of Base64 API

The first is the commonly used Apache Commons Codec library org.apache.commons.codec.binary.Base64;
The second one is the static method com.google.common.io.BaseEncoding.base64() in the Google Guava library;
The third one is net.iharder.Base64, this jar package is just one class;
The last one, MigBase64, is known as the fastest Base64 encoding, and it was implemented 10 years ago. Whether it can maintain this title now, you will know after a test;

Base64 encoding performance test

The above mentioned a total of 7 ways to implement Base64 encoding, 3 in Jdk, and 4 in third parties. Once If you have a choice, it is necessary to compare them. Performance testing is the most direct way

First define twointerfaces


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;
  }

The difference between the two interfaces is that one of the interface method parameters receives a byte array and returns a byte array, because byte->byte has lower performance than String->byte or byte->String. A little faster, so separate two groups for testing


##

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() };

As can be seen from the above, there are only 4 APIs that support byte->byte;


7 Base64 implementation classes


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 );
    }
  }
..............

The following code is basically the code for various APIs to implement Base64. Listed in detail.


The main test method is to generate 100M random numbers, divide them into 100byte or 1000byte blocks, and then encode and decode them respectively, and record the time, as follows



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 );
  }

Test results

jvm parameters: -Xms512m -Xmx4G

Everything is Obviously, from the above, it can be seen that the performance of sun is not very good. The performance of IHarder and MigBase64 is acceptable. It is said that MigBase64 has the best performance. That is the past. In this test result, the new java8 base64 has the best running speed. javaXml performs second best.


Summary

If you need a Base64 codec with good performance and reliability, don’t look for one outside the JDK, use java in java8 .util.Base64 and javax.xml.bind.DatatypeConverter, which are deeply hidden in java6, are both good choices.

The above is the detailed content of Interpretation of new features of Java8--Base64. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn