一、前言
在Java中从Java 8开始,使用java.util.Base64
类可以方便地对字符串(实际上是字符串的字节表示)进行Base64编码和解码。尤其是在需要安全地通过网络传输敏感信息或者对二进制数据进行编码以符合某些协议要求时使用。由于字符串在Java中是以字符数组(char[]
)的形式存在,而Base64操作是基于字节数组(byte[]
)的,因此在进行Base64编码或解码之前,你需要将字符串转换为字节数组,并在需要时将字节数组转换回字符串。
Base64是网络上用于传输8Bit字节码的编码方式之一,它是基于64个可打印字符来表示二进制数据的方法。Base64编码可用于在HTTP环境下传递较长的标识信息,比如JWT(JSON Web Tokens)的签名部分经常是Base64编码的。
Base64编码具有不可读性,需要解码后才能阅读原始内容,但它并不提供任何形式的安全性,因为它是一种编码方式,而不是加密算法。
Base64编码原理是将3个字节的二进制数据转换成4个6位(共24位)的二进制数据,再将这24位二进制数据分成4组,每组6位,并在每组前面加两个0凑足一个字节(因为2的6次方等于64,即每组6位二进制数可以表示64种不同的状态,因此得名Base64)。这样,每3个字节的原始数据就被编码成了4个字节的Base64编码数据。
由于Base64编码后的长度是原始数据的4/3倍(向上取整),因此它不适合对大量数据进行编码。同时,由于编码后的数据长度是4的倍数,如果原始数据长度不是3的倍数,那么在编码时需要在数据末尾添加若干个'='号进行填充,以确保编码后的长度是4的倍数。
Base64编码的字符集包括大写字母A-Z、小写字母a-z、数字0-9、加号(+)、斜杠(/)以及用于填充的等号(=)。在URL等特定场景下,加号(+)和斜杠(/)可能会被替换为其他字符(比如减号(-)和下划线(_)),以避免与URL中的保留字符冲突。这种变体被称为URL安全的Base64编码。
二、加密&解密
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class Base64Example {
public static void main(String[] args) {
// 待编码的字符串
String originalString = "今晚打老虎";
// 对字符串进行Base64编码
String encodedString = encodeBase64(originalString);
System.out.println("Base64编码后的字符串: " + encodedString);
// 对Base64编码后的字符串进行解码
String decodedString = decodeBase64(encodedString);
System.out.println("解码后的原始字符串: " + decodedString);
}
// 字符串的Base64编码方法
public static String encodeBase64(String input) {
// 使用UTF-8字符集将字符串转换为字节数组
byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
// 对字节数组进行Base64编码
return Base64.getEncoder().encodeToString(bytes);
}
// Base64编码字符串的解码方法
public static String decodeBase64(String input) {
// 对Base64编码的字符串进行解码,得到字节数组
byte[] bytes = Base64.getDecoder().decode(input);
// 使用UTF-8字符集将字节数组转换回字符串
return new String(bytes, StandardCharsets.UTF_8);
}
}
三、技巧详解
-
originalString.getBytes()
方法默认使用平台的默认字符集将字符串转换为字节序列。如果你需要指定字符集(比如UTF-8),应该使用originalString.getBytes(StandardCharsets.UTF_8)
。 -
Base64.getEncoder()
返回一个Base64.Encoder
实例,该实例的encodeToString
方法接受一个字节数组作为输入,并返回一个包含Base64编码字符串的String
。 -
编码后的字符串长度是原始字符串长度的4/3倍(向上取整),并可能包含
+
、/
字符(URL安全的Base64编码会将+
替换为-
,/
替换为_
,并在末尾可能需要=
进行填充) -
如果你需要进行URL安全的Base64编码,可以使用
Base64.getUrlEncoder()
代替Base64.getEncoder()
;这样,编码后的字符串就会使用-
和_
代替+
和/
,并且不会包含\n
或\r
等换行符,更适合在URL中使用。// 使用URL安全的Base64编码器 String string1= "http://www.baidu.com/api/customer/list"; String string2 = "type=mall&code=123"; String string3 = "http://www.baidu.com/api/customer/list?type=mall&code=123"; String urlEncodedString1 = Base64.getUrlEncoder().encodeToString(string1.getBytes(StandardCharsets.UTF_8)); String urlEncodedString2 = Base64.getUrlEncoder().encodeToString(string2.getBytes(StandardCharsets.UTF_8)); String urlEncodedString3 = Base64.getUrlEncoder().encodeToString(string3.getBytes(StandardCharsets.UTF_8)); System.out.println("URL安全的Base64编码后的字符串1: " + urlEncodedString1); System.out.println("URL安全的Base64编码后的字符串2: " + urlEncodedString2); System.out.println("URL安全的Base64编码后的字符串3: " + urlEncodedString3);
URL安全的Base64编码后的字符串1: aHR0cDovL3d3dy5iYWlkdS5jb20vYXBpL2N1c3RvbWVyL2xpc3Q=
URL安全的Base64编码后的字符串2: dHlwZT1tYWxsJmNvZGU9MTIz
URL安全的Base64编码后的字符串3: aHR0cDovL3d3dy5iYWlkdS5jb20vYXBpL2N1c3RvbWVyL2xpc3Q_dHlwZT1tYWxsJmNvZGU9MTIz