Java 编码和加密

Base64 编码

Base64 原理

Base64 内容传送编码是一种以任意 8 位字节序列组合的描述形式,这种形式不易被人直接识别。

Base64 是一种很常见的编码规范,其作用是将二进制序列转换为人类可读的 ASCII 字符序列,常用在需用通过文本协议(比如 HTTP 和 SMTP)来传输二进制数据的情况下。Base64 并不是加密解密算法,尽管我们有时也听到使用 Base64 来加密解密的说法,但这里所说的加密与解密实际是指编码(encode) 和 解码(decode)的过程,其变换是非常简单的,仅仅能够避免信息被直接识别。

Base64 算法主要是将给定的字符以字符编码(如 ASCII 码,UTF-8 码)对应的十进制数为基准,做编码操作:

  1. 将给定的字符串以字符为单位,转换为对应的字符编码。
  2. 将获得字符编码转换为二进制
  3. 对二进制码做分组转换,每 3 个字节为一组,转换为每 4 个 6 位二进制位一组(不足 6 位时低位补 0)。这是一个分组变化的过程,3 个 8 位二进制码和 4 个 6 位二进制码的长度都是 24 位(3*8 = 4*6 = 24)。
  4. 对获得的 4-6 二进制码补位,向 6 位二进制码添加 2 位高位 0,组成 4 个 8 位二进制码。
  5. 对获得的 4-8 二进制码转换为十进制码。
  6. 将获得的十进制码转换为 Base64 字符表中对应的字符。

Base64 编码表

索引 对应字符 索引 对应字符 索引 对应字符 索引 对应字符
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w
15 P 32 g 49 x
16 Q 33 h 50 y

1

Base64 应用

Base64 编码可用于在 HTTP 环境下传递较长的标识信息。在其他应用程序中,也常常需要把二进制数据编码为适合放在 URL(包括隐藏表单域)中的形式。此时,采用 Base64 编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到,算是起到一个加密的作用。

然而,标准的 Base64 并不适合直接放在 URL 里传输,因为 URL 编码器会把标准 Base64 中的 /+ 字符变为形如 %XX 的形式,而这些 % 号在存入数据库时还需要再进行转换,因为 ANSI SQL 中已将 % 号用作通配符。

为解决此问题,可采用一种用于 URL 的改进 Base64 编码,它不仅在末尾填充 = 号,并将标准 Base64 中的“+”和“/”分别改成了 -_,这样就免去了在 URL 编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

另有一种用于正则表达式的改进 Base64 变种,它将 +/ 改成了 !-,因为 +, * 以及前面在 IRCu 中用到的 [] 在正则表达式中都可能具有特殊含义。

【示例】java.util.Base64 编码、解码示例

Base64.getEncoder()Base64.getDecoder() 提供了的是标准的 Base64 编码、解码方式;

Base64.getUrlEncoder()Base64.getUrlDecoder() 提供了 URL 安全的 Base64 编码、解码方式(将 +/ 替换为 -_)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Base64Demo {

public static void main(String[] args) {
String url = "https://www.baidu.com";
System.out.println("url:" + url);
// 标准的 Base64 编码、解码
byte[] encoded = Base64.getEncoder().encode(url.getBytes(StandardCharsets.UTF_8));
byte[] decoded = Base64.getDecoder().decode(encoded);
System.out.println("Base64 encoded:" + new String(encoded));
System.out.println("Base64 decoded:" + new String(decoded));
// URL 安全的 Base64 编码、解码
byte[] encoded2 = Base64.getUrlEncoder().encode(url.getBytes(StandardCharsets.UTF_8));
byte[] decoded2 = Base64.getUrlDecoder().decode(encoded2);
System.out.println("Url Safe Base64 encoded:" + new String(encoded2));
System.out.println("Url Safe Base64 decoded:" + new String(decoded2));
}

}

输出:

1
2
3
4
5
url:https://www.baidu.com
Base64 encoded:aHR0cHM6Ly93d3cuYmFpZHUuY29t
Base64 decoded:https://www.baidu.com
Url Safe Base64 encoded:aHR0cHM6Ly93d3cuYmFpZHUuY29t
Url Safe Base64 decoded:https://www.baidu.com

参考