Java Base64 Encoding and Decoding – Java Base64 编码和解码

最后修改: 2015年 8月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we explore the various utilities that provide Base64 encoding and decoding functionality in Java.

在本教程中,我们将探讨在Java中提供Base64编码和解码功能的各种实用程序。

We’re mainly going to illustrate the new Java 8 APIs. Also, we use the utility APIs of Apache Commons.

我们主要是要说明新的Java 8 APIs。另外,我们还使用Apache Commons的实用API。

2. Java 8 for Base 64

2.Java 8 for Base 64

Java 8 has finally added Base64 capabilities to the standard API, via the java.util.Base64 utility class.

Java 8终于通过java.util.Base64实用类将Base64功能添加到标准API中。

Let’s start by looking at a basic encoder process.

让我们先来看看一个基本的编码器过程。

2.1. Java 8 Basic Base64

2.1.Java 8 基本 Base64

The basic encoder keeps things simple and encodes the input as-is, without any line separation.

基本编码器保持简单,对输入进行原样编码,没有任何分线。

The encoder maps the input to a set of characters in the A-Za-z0-9+/ character set.

编码器将输入映射为A-Za-z0-9+/字符集中的一组字符。

Let’s first encode a simple String:

让我们首先编码一个简单的String

String originalInput = "test input";
String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());

Note how we retrieve the full Encoder API via the simple getEncoder() utility method.

注意我们是如何通过简单的getEncoder()实用方法来检索完整的编码器API的。

Let’s now decode that String back to the original form:

现在让我们把这个String解码成原始形式。

byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);

2.2. Java 8 Base64 Encoding Without Padding

2.2.Java 8无填充的Base64编码

In Base64 encoding, the length of an output-encoded String must be a multiple of three. The encoder adds one or two padding characters (=) at the end of the output as needed in order to meet this requirement.

在Base64编码中,输出编码的String的长度必须是3的倍数。编码器会根据需要在输出的最后添加一个或两个填充字符(=),以满足这一要求。

Upon decoding, the decoder discards these extra padding characters. To dig deeper into padding in Base64, check out this detailed answer on Stack Overflow.

解码时,解码器会丢弃这些额外的填充字符。要深入了解Base64中的填充,请查看Stack Overflow上的这个详细答案

Sometimes, we need to skip the padding of the output. For instance, the resulting String will never be decoded back. So, we can simply choose to encode without padding:

有时,我们需要跳过输出的padding。例如,产生的String将永远不会被解码回来。所以,我们可以简单地选择不加填充的编码

String encodedString = 
  Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes());

2.3. Java 8 URL Encoding

2.3. Java 8 URL 编码

URL encoding is very similar to the basic encoder. Also, it uses the URL and Filename Safe Base64 alphabet. In addition, it does not add any line separation:

URL 编码与基本编码器非常相似。而且,它使用URL和Filename Safe Base64字母。此外,它不添加任何行间分隔。

String originalUrl = "https://www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java";
String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes());

Decoding happens in much the same way. The getUrlDecoder() utility method returns a java.util.Base64.Decoder. So, we use it to decode the URL:

解码的方式大致相同。getUrlDecoder() 工具方法返回一个java.util.Base64.Decoder。因此,我们用它来解码URL。

byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl);
String decodedUrl = new String(decodedBytes);

2.4. Java 8 MIME Encoding

2.4.

Let’s start by generating some basic MIME input to encode:

让我们先生成一些基本的MIME输入来进行编码。

private static StringBuilder getMimeBuffer() {
    StringBuilder buffer = new StringBuilder();
    for (int count = 0; count < 10; ++count) {
        buffer.append(UUID.randomUUID().toString());
    }
    return buffer;
}

The MIME encoder generates a Base64-encoded output using the basic alphabet. However, the format is MIME-friendly.

MIME编码器使用基本字母表生成一个Base64编码的输出。然而,该格式是对MIME友好的。

Each line of the output is no longer than 76 characters. Also, it ends with a carriage return followed by a linefeed (\r\n):

输出的每一行都不超过76个字符。另外,它以回车键和换行键结束(\r\n)。

StringBuilder buffer = getMimeBuffer();
byte[] encodedAsBytes = buffer.toString().getBytes();
String encodedMime = Base64.getMimeEncoder().encodeToString(encodedAsBytes);

In the decoding process, we can use the getMimeDecoder() method that returns a java.util.Base64.Decoder:

在解码过程中,我们可以使用getMimeDecoder()方法,返回一个java.util.Base64.Decoder

byte[] decodedBytes = Base64.getMimeDecoder().decode(encodedMime);
String decodedMime = new String(decodedBytes);

3. Encoding/Decoding Using Apache Commons Code

3.使用Apache Commons代码进行编码/解码

First, we need to define the commons-codec dependency in the pom.xml:

首先,我们需要在commons-codec pom.xml中定义依赖。

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

The main API is the org.apache.commons.codec.binary.Base64 class. We can initialize it with various constructors:

主要的API是org.apache.commons.codec.binary.Base64类。我们可以用各种构造函数来初始化它。

  • Base64(boolean urlSafe) creates the Base64 API by controlling the URL-safe mode (on or off).
  • Base64(int lineLength) creates the Base64 API in a URL-unsafe mode and controls the length of the line (default is 76).
  • Base64(int lineLength, byte[] lineSeparator) creates the Base64 API by accepting an extra line separator, which by default is CRLF (“\r\n”).

Once the Base64 API is created, both encoding and decoding are quite simple:

一旦创建了Base64 API,编码和解码都很简单。

String originalInput = "test input";
Base64 base64 = new Base64();
String encodedString = new String(base64.encode(originalInput.getBytes()));

Moreover, the decode() method of the Base64 class returns the decoded string:

此外,Base64类的decode()方法返回解码后的字符串。

String decodedString = new String(base64.decode(encodedString.getBytes()));

Another option is using the static API of Base64 instead of creating an instance:

另一个选择是使用Base64的静态API,而不是创建一个实例。

String originalInput = "test input";
String encodedString = new String(Base64.encodeBase64(originalInput.getBytes()));
String decodedString = new String(Base64.decodeBase64(encodedString.getBytes()));

4. Converting a String to a byte Array

4.将字符串转换为字节阵列

Sometimes, we need to convert a String to a byte[]. The simplest way is to use the String getBytes() method:

有时,我们需要将一个String转换为byte[]。最简单的方法是使用String getBytes()方法。

String originalInput = "test input";
byte[] result = originalInput.getBytes();

assertEquals(originalInput.length(), result.length);

We can provide encoding as well and not depend on default encoding. As a result, it’s system-dependent:

我们也可以提供编码,不依赖默认编码。因此,它是依赖于系统的。

String originalInput = "test input";
byte[] result = originalInput.getBytes(StandardCharsets.UTF_16);

assertTrue(originalInput.length() < result.length);

If our String is Base64 encoded, we can use the Base64 decoder:

如果我们的字符串Base64编码的,我们可以使用Base64解码器

String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = Base64.getDecoder().decode(originalInput);

assertEquals("test input", new String(result));

We can also use the DatatypeConverter parseBase64Binary() method:

我们也可以使用DatatypeConverter parseBase64Binary()方法

String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = DatatypeConverter.parseBase64Binary(originalInput);

assertEquals("test input", new String(result));

Finally, we can convert a hexadecimal String to a byte[] using the DatatypeConverter.parseHexBinary method:

最后,我们可以使用DatatypeConverter.parseHexBinarymethod将一个十六进制String转换为byte[]

String originalInput = "7465737420696E707574";
byte[] result = DatatypeConverter.parseHexBinary(originalInput);

assertEquals("test input", new String(result));

5. Conclusion

5.结论

This article explained the basics of how to do Base64 encoding and decoding in Java. We used the new APIs introduced in Java 8 and Apache Commons.

这篇文章解释了如何在Java中进行Base64编码和解码的基础知识。我们使用了Java 8和Apache Commons中引入的新API。

Finally, there are a few other APIs that provide similar functionality: java.xml.bind.DataTypeConverter with printHexBinary and parseBase64Binary.

最后,还有一些提供类似功能的API。java.xml.bind.DataTypeConverter具有printHexBinaryparseBase64Binary

Code snippets can be found over on GitHub.

代码片段可以在GitHub上找到over