过去一直没搞懂base64是什么,最近看了阮一峰的笔记后,自己查了部分资料后才搞明白是什么。原来base64也像我之前做的UTF-8笔记一样,进行了编码,是为了解决电子邮件中不能直接使用非ASCII码字符的规定的问题。当然,现在我们常常是在图片中使用base64,减少请求次数。
1、什么是base64
我们都知道,ASCII码字符集只有128个字符,对于美国人可能还够用,但是对于其他国家来说就远远不够了。于是出现了Unicode字符集,它几乎囊括了所有你能见到的文字。并且还在不断发展。但是Unicode组织是在1988年才成立,那在这之前常用的字符集是什么?ASCII字符集。所以1982年给电子邮件定规范的时候,就规定了电子邮件只能使用ASCII字符。这当然不利于电子邮件发展,你想,你写一封电子邮件还得用英文写。。。因此1992年,工程师们决定扩展电子邮件的技术规范,提出一系列补充规范,出现了MIME。MIME使用了Quoted-printable和Base64对邮件重新进行了编码,将那些非ASCII字符转成ASCII字符,关于MIME的介绍,可以看阮一峰的MIME笔记。这里主要介绍base64。
2、base64的编码方式
好的,我们已经知道base64是用来将非ASCII字符转化为ASCII字符的。那么它具体是怎么实现的呢?它的规则如下:
- 首先将每3个字节分为一组,这样就一共是24个二进制位
- 接着将24个二进制位分成4组,每组6个二进制位
- 再在每组前面补充2个0,这样每组就是8个二进制位,共有4个字节
- 最后每个字节根据下表一一对应,组合起来就是编码完成的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
上表来自阮一峰-Base64笔记
举个例子,现在我们要把sea转化为base64。sea由3个字母组成,每个字母对应一个字节。它们的ASCII值分别是115、101、97,转成二进制分别是01110011、01100101、01100001。组合起来就是011100110110010101100001,分成4组就是011100-110110-010101-100001(这里为了区分使用-进行了分割,后文类似)。再在每组前面添2个0,就是00011100-00110110-00010101-00100001。转成10进制,28-54-21-33,再根据上表对应得到base64值为c2Vh。
但是有时候字节数不是3的倍数,这样会余下1个或2个字节。这种情况的处理方法如下:
- 二个字节的情况:将这二个字节的一共16个二进制位,按照上面的规则,转成三组,最后一组除了前面加两个0以外,后面也要加两个0。这样得到一个三位的Base64编码,再在末尾补上一个"="号。
- 一个字节的情况:将这一个字节的8个二进制位,按照上面的规则转成二组,最后一组除了前面加二个0以外,后面再加4个0。这样得到一个二位的Base64编码,再在末尾补上两个"="号。
举个例子,如果我们要将se转成base64,根据上文我们知道它的二进制是01110011-01100101,根据每组6位可以分为011100-110110-0101,再由上面的规则可以写成00011100-00110110-00010100,转成10进制为28-54-20,这样base64为c2U=。别忘了最后的那个=号。
如果要将s转成base64,根据上文我们知道它的二进制是01110011,根据每组6位可以分为011100-11,再由上面的规则可以写成00011100-00110000,转成10进制为28-48,这样base64为cw==。别忘了最后的那2个=号。
上面的例子都是英文的,那么肯定有小伙伴要问了,中文怎么办?这里需要考虑到编码方式,汉字有多种编码方式,如gb2312、utf-8、gbk等等。不同编码方式对应的base64是不同的。不知道什么是编码可以看我的笔记。因为网页通常使用utf-8编码,这里以utf-8编码作为例子。
假设我们要把汉字好转成base64。步骤如下:
好字的utf-8编码是E5A5BD,转成二进制是11100101-10100101-10111101,按每6个一组为111001-011010-010110-111101- 在每组的前面添加2个0,得到
00111001-00011010-00010110-00111101,转成10进制为57-26-22-61 - 对应规则表得到
base64为5aW9
那么我们每次想要转换base64都要这么搞吗?当然不是的,网上有很多在线转化base64的网站。例如:base64在线转化。在JavaScript中也有两个函数可以用于base64编码和解码,分别是btoa()和atob。例如上面的例子,要对sea进行base64编码可以这样:btoa('sea')。得到结果是c2Vh,解码可以这样:atob('c2Vh'),返回sea。但是这两个函数只适用于ASCII字符集里面的字符。就,,,没什么用。
3、base64的优缺点
base64初衷是应用于电子邮件,将非ASCII字符转化为ASCII字符。但是现在常常用于图片的转化。在图片中我们可以这么使用:<img src="https://img-blog.csdnimg.cn/2022010703501249031.png" />。其中data:image/png;base64,为固定前缀,表示使用base64,image/png表示这是一个png图片。同样,也可以用在背景图片中,url(https://img-blog.csdnimg.cn/2022010703501249031.png)。
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAAmJLR0QA/4ePzL8AAAKLSURBVEjHjZW/T1NRFMc/valY0FgWI0U0pUgCQWXgxyYOuEOiDPBHMEiMpQEkMWmJ2sGdjQQHGERWGXTERoOkQgJio9ZqXFqCWEjDJfe9Png/S793ae4532/PPefd+/VJXBCgh9s000AdsM9vvvGZDxSdqU6BBoboI+AiW+Q9i+QqCdQwzCB+JGlSfCHHHnCREO300IGPEq95xaG7QIgoESRvWbD/Tzk+xD187DBjiktjtcg5uSxnZaukwmqVs3JZzsmIkWNUEOI5QdaZYdetqyZcYpybFHikVyHKZ48S5BNTZ9Jhl0k+EmScmlOBYSJkSVA6k65QIkGWZkYMgRCDHJHkf1V0tIEmOWKAkC7wAD8rbFVNV9hiBT9DSqCWPiQLlvBjnhG07AR5yQvLzgKSO9QKugmQts39Mu3ETRL1JIhwzpKTI02AbkEnkLIV+JTvXD+RqCfONX7wxJalWJ2CMLBhCxWInUgY9Bh5W9YmEParTvLL0SQlEdckfB50yKoJCu3C7jmCp1V40XVWnXAJGPDh036pT94Tgn3twjphnN3cTisUa19oA2z0pMdM7bTjqhqmIAO0edLzlolYoVgZwRrQYwtNWVpnSEzasrqBNUGKIh3aMM393bZ0Xkls8NeSE6KDA1KqxaNyWY5WfIfcVpkltGtRop/WCgN14gb9lFjUr3OOJQQPXZ9ydwQYQ/BGfcH6hzRPhiai+Kui+4nSRIZ5Tp60Q+IU6GKiiioCTNBFgTgHWHyhhWnq+UmS7YpnH6OJPNN81TesxhIjXIWxZIifxu3WNsJA2dpW2TRZWxu9ZWtbYt7L2nQ0cp+7nHep4JB3LNrfDi977+UWEa5wAfjHH3ZYZ9Vh78AxZeQKo4xU7NcAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC" />
但是base64也有它的缺点,从上面的转化过程我们已经知道,一个3字节的东西转为base64后会变成4字节,这样增加了文件体积。小的图片还好,如果是大图,就不推荐使用base64了,因为会导致文件体积过大,增大了大约三分之一的体积。
以上。
4、参考链接
1. 阮一峰 - MIME笔记
2. 阮一峰 - Base笔记
本文详细介绍了Base64编码的原理及其应用场景,包括其在电子邮件和图片格式转换中的作用,并探讨了Base64编码的优缺点。
1492

被折叠的 条评论
为什么被折叠?



