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);
如果我们的String是Base64编码的,我们可以使用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));