鸣谢CSDN文章:https://blog.csdn.net/believesoul/article/details/84100616
一、言简意赅理解Base64编码
就是将以“字节”为单位的二进制数据,转换为肉眼可见的64个“可打印字符”字符串的编码方法。
啥是以“字节”为单位的二进制数据???
长得类似这个样子:
b'Cxe8xafxadxe8xa8x80xe4xb8xadxe6x96x87xe7xbdx918xe5xb2x81xe4xbax86' = bytes('C语言中文网8岁了', encoding='UTF-8')
详见:https://www.cnblogs.com/zhangmingda/p/14123752.html
二、为啥要做编码转换?
答:一般用于在HTTP协议下传输二进制数据,由于HTTP协议是文本协议,所以在HTTP协议下传输二进制数据需要将二进制数据转换为字符数据。然而直接转换是不行的。因为网络传输只能传输可打印字符。
这玩意只是编码,不是加密,但是肉眼看不出原始内容
三、转换为哪64个可打印字符?
答:是ASCII码里面95个可打印字符中筛选出了64个:即后面括号内 [0-9a-zA-Z+/=] 即数字0到9,大小写字母 和 +/= 实际为65个可打印字符。
具体什么是可打印字符?在ASCII码中规定,0-31、128这33个字符属于控制字符,32-127这95个字符属于可打印字符,也就是说网络传输只能传输这95个字符,不在这个范围内的字符无法传输。那么该怎么才能传输其他字符呢?其中一种方式就是使用Base64。
Base64,就是使用64个可打印字符来表示二进制数据的方法。这64个字符中包括大小写字母、数字、+和/,还有用来补缺的特殊字符=。
注意:由于base64编码用了8位字符来表示信息中的6个位,所以base64编码字符串大约比原始值扩大了33%。
Base64的索引与对应字符的关系如下表所示:
也就是说,如果将索引转换为对应的二进制数据的话需要至多6个Bit。然而ASCII码需要8个Bit来表示,那么怎么使用6个Bit来表示8个Bit的数据呢?6个Bit当然不能存储8个Bit的数据,但是4×6个Bit可以存储3×8个Bit的数据啊!如下表所示:
可以看到“Son”通过Base64编码转换成了“U29u”。这是刚刚好的情况,3个ASCII字符刚好转换成对应的4个Base64字符。但是,当需要转换的字符数不是3的倍数的情况下该怎么办呢?Base64规定,当需要转换的字符不是3的倍数时,一律采用补0的方式凑足3的倍数,具体如下表所示:
每6个Bit为一组,第一组转换后为字符“U”,第二组末尾补4个0转换后为字符“w”。剩下的使用“=”替代。即字符“S”通过Base64编码后为“Uw==”。这就是Base64的编码过程。
如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。
这是字节的位总数不是6的倍数的情况,当剩下4位时,我们需要补2个=凑齐8的倍数;当剩下的是2位时,我们需要补齐1个 = 抽泣8的倍数。
四、Base64怎么用?
Python3计算Base64
import base64 str1 = "hello world!" base64.encodebytes(str1.encode()) b'aGVsbG8gd29ybGQh ' base64.encodebytes(str1.encode()).decode() 'aGVsbG8gd29ybGQh ' base64.encodebytes(str1.encode()).decode('utf-8') 'aGVsbG8gd29ybGQh '
Java计算Base64,使用的时候直接调用内部模块即可。具体代码如下所示:
package com.first; import org.junit.Test; import java.io.UnsupportedEncodingException; import java.util.Base64; public class Test { @Test public void test() throws UnsupportedEncodingException { // 编码 String encode = Base64.getEncoder().encodeToString("So".getBytes("UTF-8")); System.out.println(encode); // 解码 byte[] decode = Base64.getDecoder().decode(encode); System.out.println(new String(decode, "UTF-8")); } }
五、Base64的相关点
- 首先这算法是编码,不是压缩,编码后只会增加字节数;字节数会成为原字节数的4/3;
- 算法简单, 几乎不会影响效率;
- 算法可逆, 解码很方便, 不用于私密信息通信;
- 虽然解码方便, 但毕竟编码了, 肉眼还是不能直接看出原始内容;
- 加密后的字符串只有[0-9a-zA-Z+/=],不可打印字符(包括转移字符)也可传输;