版权声明:转载请注明出处 https://blog.csdn.net/laozhaishaozuo/article/details/82287321
- 什么是Base64算法
- Base64算法的应用
- Java中使用Base64算法
什么是Base64算法
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.百度百科
在早期,Base64编码算法主要是为了解决电子邮件传送问题。在某些很古老的邮件服务器只支持ASCII码字符,对于非ASCII码字符可能做调整将最高位置0,造成乱码。为了解决该问题诞生了Base64编码。
编码表
编码表如下
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
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 (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Base64Url与其类似,不过最后两位不同
Table 2: The "URL and Filename safe" Base 64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
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 - (minus)
12 M 29 d 46 u 63 _
13 N 30 e 47 v (underline)
14 O 31 f 48 w
15 P 32 g 49 x
16 Q 33 h 50 y (pad) =
算法
经过Base64编码之后,密码长度变为了原来的4/3倍。
具体算法如下:
1. 将对应的字符串以字符为单位,转换为对应的字符编码
2. 将获得的字符编码转化为二进制
3. 将获得的二进制码每3个8位二进制为一组,转换为每4个6位二进制一组,3*8=4*6,如果最后一组不够3个,则最终结果将会添加一个或两个 (pad) =
4. 将获得的6位二进制高位补0,成为8进制,变为4个8位二进制一组
5. 将4个8位二进制转换为10进制码
6. 在上述转换表中找到对应的字符
举个例子
内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100 110011 000100 110011
然后计算机是8位8位的存数 6不够,自动就补两个高位0了
所有有了 高位补0: 00011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z
如果最终转码之后,不够4位,则以=代替
转前:A
先转成ascii:对应 65
2进制: 01000001
6个一组(2组): 010000 01
不够6位补零:010000 010000
高位补0:00010000 00010000
得到 16 16
查对下照表:QQ
最终结果:QQ==
Base64算法的应用
Base64算法有很多用途
1. 用于邮件传输
2. 用于网络数据传输,比如说图片
3. 数字证书存储
4. 密钥存储
Java中使用Base64算法
对于Base64这种常用算法,Jdk直到1.8之后才增加。
我们可以使用Java来验证,上文中的例子
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Arrays;
import org.junit.Test;
import com.google.common.base.Charsets;
public class Base64Test {
@Test
public void testBase64() throws IOException {
byte[] data = new String("s13").getBytes(Charsets.UTF_8);
System.out.println(Arrays.toString(data));
for (byte i : data) {
System.out.println(Integer.toBinaryString(i));
}
System.out.println(new String(data));
byte[] result = org.bouncycastle.util.encoders.Base64.encode(data);
byte[] jdkBase = java.util.Base64.getEncoder().encode(data);
assertEquals(Arrays.toString(result), Arrays.toString(jdkBase));
System.out.println(Arrays.toString(jdkBase));
System.out.println(new String(result));
}
@Test
public void testA() throws IOException {
byte[] data = new String("A").getBytes(Charsets.UTF_8);
System.out.println(Arrays.toString(data));
for (byte i : data) {
System.out.println(Integer.toBinaryString(i));
}
System.out.println(new String(data));
byte[] result = org.bouncycastle.util.encoders.Base64.encode(data);
byte[] jdkBase = java.util.Base64.getEncoder().encode(data);
assertEquals(Arrays.toString(result), Arrays.toString(jdkBase));
System.out.println(Arrays.toString(jdkBase));
System.out.println(new String(result));
}
}