Contents

Java base64编码和解码

1. 概述

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

我们将主要说明新的 Java 8 API。此外,我们使用 Apache Commons 的实用程序 API。

2. 用于 Base 64 的 Java 8

Java 8 终于通过java.util.Base64实用程序类向标准 API添加了 Base64 功能。 让我们从一个基本的编码器过程开始。

2.1. Java 8 基本 Base64

基本编码器使事情变得简单,并按原样对输入进行编码,没有任何行分隔。

编码器将输入映射到*A-Za-z0-9+/*字符集中的一组字符。因此,解码器拒绝该集合之外的任何字符。

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

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

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

现在让我们将该string解码回原始形式:

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

2.2. 无填充的 Java 8 Base64 编码

在 Base64 编码中,输出编码字符串的长度必须是三的倍数。编码器根据需要在输出末尾添加一个或两个填充字符 ( = ) 以满足此要求。

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

有时,我们需要跳过 output 的填充。例如,生成的字符串永远不会被解码回来。因此,我们可以简单地选择不使用填充进行编码

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

2.3. Java 8 URL 编码

URL 编码与基本编码器非常相似。此外,它使用 URL 和文件名 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());

解码以几乎相同的方式发生。getUrlDecoder ()实用程序方法返回java.util.Base64.Decoder。因此,我们使用它来解码 URL:

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

2.4. Java 8 MIME 编码

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

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

MIME 编码器使用基本字母表生成 Base64 编码的输出。但是,该格式是 MIME 友好的。 输出的每一行不超过 76 个字符。此外,它以回车结束,后跟换行符(\r\n):

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

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

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

3. 使用 Apache Commons Code 编码/解码

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

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

主要 API 是org.apache.commons.codec.binary.Base64类。我们可以使用各种构造函数对其进行初始化:

  • *Base64(boolean urlSafe)*通过控制 URL 安全模式(打开或关闭)来创建 Base64 API。
  • *Base64(int lineLength)*在 URL 不安全模式下创建 Base64 API 并控制行的长度(默认为 76)。
  • *Base64(int lineLength, byte[] lineSeparator)*通过接受额外的行分隔符创建 Base64 API,默认情况下为 CRLF (“\r\n”)。

创建 Base64 API 后,编码和解码都非常简单:

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

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

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

另一种选择是使用Base64的静态 API而不是创建实例:

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

4. 将 String转换为byte数组

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

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

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

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

如果我们的StringBase64编码的,我们可以使用Base64解码器

String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = Base64.getDecoder().decode(originalInput);
assertEquals("test input", new String(result));

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

String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = DatatypeConverter.parseBase64Binary(originalInput);
assertEquals("test input", new String(result));

最后,我们可以使用DatatypeConverter.parseHexBinary方法将十六进制String转换为byte[]

String originalInput = "7465737420696E707574";
byte[] result = DatatypeConverter.parseHexBinary(originalInput);
assertEquals("test input", new String(result));