用途

  1. 表示二进制数据,可用于传输二进制数据,如文件、缩略图等
  2. 对数据起一定加密效果

转换原理

    Base64算法,是用64个可打印字符表示二进制所有数据方法。Base64字符成包含A—Z,a—z,0—9,+,/ ,他们编码对应表如下。
编码表
    一个Base64字符编码转换成二进制都是8个bit位,而前两位都00,有效数字只有6个bit位,也就是说只需要6个bit位就能表示1个Base64字符,而正常的字符是使用8个bit位表示, 8和6的最小公倍数是24,所以4个Base64字符可以表示3个标准的ascii字符。

    按照以上原理,我们将要加密的明文对应的ascii值转换成二进制并拼接在一起,将其分为每6个bit为一份,每4份为一组。不够6个bit位的用0补充,不够4份的用=补充。根据base64编码表将每一份转成对应的Base64字符,得到的也就是密文。

转换过程

  1. 得到明文每一个字符对应的ascii码
  2. 将ascii码转换成二进制,并拼接在一起
  3. 将拼接在一起的二进制,分为6个bit位为一份,4份为一组
  4. 将每一份根据base64编码表转换成base64字符
  5. 最后不够6个bit位的用0补充,不够一组的用=补充为4份

实践

不需要补充0或=(明文:Man)
  1. 将明文每一个字符对应的ascii码
    M 对应ascii码 :77
    a 对应ascii码 :97
    n 对应ascii码 :110
  2. 将ascii码转换成二进制,并拼接在一起
    77 二进制 : 01001101
    97 二进制 : 01100001
    110 二进制 : 01101110
    拼接 : 010011010110000101101110
  3. 分为6个bit位为一份,4份为一组
    010011
    010110
    000101
    101110
  4. 每一份根据base64编码表转换成base64字符
    010011 十进制 : 19 : base64字符 : T
    010110 十进制 : 22 : base64字符 : W
    000101 十进制 : 5 : base64字符 : F
    101110 十进制 : 46 : base64字符 : u
  5. 详解图
    详解图
需要补充0或=(明文:BC)
  1. 将明文每一个字符对应的ascii码
    B 对应ascii码 :66
    C 对应ascii码 :67
  2. 将ascii码转换成二进制,并拼接在一起
    66 二进制 : 01000010
    67 二进制 : 01000011
    拼接 : 0100001001000011
  3. 分为6个bit位为一份,4份为一组,补充0和=
    010000
    100100
    001100

xxxxxx
4. 每一份根据base64编码表转换成base64字符
010000 十进制 : 16 : base64字符 : Q
100100 十进制 : 36 : base64字符 : k
001100 十进制 : 12 : base64字符 : M
xxxxxx : base64字符 : =
5. 详解图
详解图

使用

    java中早已提供以上算法的jar包,不用自己去实现以上算法,个人倾向使用apache提供的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import org.apache.commons.codec.binary.Base64;

private static final String ENCODING_UTF8 = "UTF-8";

/**
* 二进制数据编码为BASE64字符串,根据isChunked是否输出换行
*/
public static String encodeBase64(byte[] bytes, boolean isChunked) {
try {
return new String(Base64.encodeBase64(bytes, isChunked), ENCODING_UTF8);
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage(), e);
return "";
}
}

/**
* BASE64解码
*/
public static byte[] decodeBase64(String encodedStr) {
byte[] result;
try {
result = Base64.decodeBase64(encodedStr);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
}
return result;
}

彩蛋

    ASCII码总共128个,用来表示英文字母、数字以及英文标点符号。而简体中文、繁体中文、日文以及韩文等都是用多字节来存储的,通常称之为多字节字符。因为Base编码的输入是字符串的编码,不同编码的字符串的Base64结果是不同的

    个人觉得用base64传输缩略图,非常合适,客户端收到base64字符后,就可以显示图片,而不用依赖网络了。这样至少可以保证缩略图一定能显示出来。但是通过以上算法,可以发现base64后的字符串大小是原来的4/3.