了解Base64
jerry2 Architect

简介

Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法。由于log264=6,所以每6个比特为一个单元,对应某个可打印字符。3个字节相当于24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示。在Base64中的可打印字符包括字母A-Za-z数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后BinHex的版本使用不同的64字符集来代表6个二进制数字,但是不被称为Base64。

Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括MIME电子邮件XML的一些复杂数据。

编码原理

十进制 二进制 字符 十进制 二进制 字符 十进制 二进制 字符 十进制 二进制 字符
0 000000 A 16 010000 Q 32 100000 g 48 110000 w
1 000001 B 17 010001 R 33 100001 h 49 110001 x
2 000010 C 18 010010 S 34 100010 i 50 110010 y
3 000011 D 19 010011 T 35 100011 j 51 110011 z
4 000100 E 20 010100 U 36 100100 k 52 110100 0
5 000101 F 21 010101 V 37 100101 l 53 110101 1
6 000110 G 22 010110 W 38 100110 m 54 110110 2
7 000111 H 23 010111 X 39 100111 n 55 110111 3
8 001000 I 24 011000 Y 40 101000 o 56 111000 4
9 001001 J 25 011001 Z 41 101001 p 57 111001 5
10 001010 K 26 011010 a 42 101010 q 58 111010 6
11 001011 L 27 011011 b 43 101011 r 59 111011 7
12 001100 M 28 011100 c 44 101100 s 60 111100 8
13 001101 N 29 011101 d 45 101101 t 61 111101 9
14 001110 O 30 011110 e 46 101110 u 62 111110 +
15 001111 P 31 011111 f 47 101111 v 63 111111 /

Base64编码的过程:

  1. 将字符串转换为字符数组;
  2. 将每个字符转换为ASCII码;
  3. 将ASCII码转换为8bit二进制码;
  4. 然后每3个字节为一组(一个字节为8个bit,所以每组24个bit);
  5. 将每组的24个bit分为4份,每份6个bit;
  6. 在每6个bit前补0,补齐8bit(前面补0不影响数值大小);
  7. 然后将每8bit转换为10进制数,根据上面的Base64编码表进行转换。

示例

hello这个字符串进行Base64编码,过程如下:

  1. hello转换为字符数组:h e l l o;
  2. 对应的ASCII码为:104 101 108 108 111;
  3. 转换为8bit二进制数:01101000 01100101 01101100 01101100 01101111
  4. 分组,每组24个bit(不足24个bit的用00000000补齐): 011010000110010101101100 011011000110111100000000;
  5. 每组24bit分为4份,每份6bit:011010 000110 010101 101100 011011 000110 111100 000000;
  6. 在每6个bit前补0,补齐8bit:00011010 00000110 00010101 00101100 00011011 00000110 00111100 00000000;
  7. 将每8bit转换为10进制数:26 6 21 44 27 6 60 0
  8. 从上面Base64编码表中找到十进制数对应的字符(末尾的0并不是A,而是用=等号补位):a G V s b G 8 =

所以hello经过Base64编码的结果为aGVsbG8=

我们可以用代码验证下:

1
2
3
public static void main(String[] args) {
System.out.println(Base64.getEncoder().encodeToString("hello".getBytes()));
}
 评论