一、什么是Base64编码?
所谓Base64,就是说选出64个字符—-小写字母a-z、大写字母A-Z、数字0-9、符号”+”、”/“(再加上作为垫字的”=”,实际上是65个字符)—-作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。
具体来说,转换方式可以分为四步:
第一步,将每三个字节作为一组,一共是24个二进制位。
第二步,将这24个二进制位分为四组,每个组有6个二进制位。
第三步,在每组前面加两个0,扩展成32个二进制位,即四个字节。
第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。
1 | 0 A 17 R 34 i 51 z |
1 | function getip() { |
Base64编码对照表
二、编码过程解析
1、举个栗子
假如,我们要对字符串yangxinmin
进行Base64编码。
1、先将yangxinmin
按3个字节为一组地分开,如yan
,gxi
,nmi
,n
2、为了省事,这里我们不全部转换,就以yan
为例
3、将y
、a
、n
3个字母的ASCII码查出来,分别是:121、97、110
4、然后将121、97、110这3个数字转换成二进制,分别是:01111001、01100001、01101110
5、将上一步3个二进制串拼装到一串:011110010110000101101110
6、然后将011110010110000101101110,从左往右数,6位为一组分开,如:011110、010110、000101、101110
7、然后将这4组二进制转换成十进制数,分别是:30、22、5、46
8、再将上一步的4个数字,对照上面的Base64编码对照表,得到结果为:eWFu,这就是我们需要的Base64编码。
前面我们说到是将字符串3个字节一组分开,但如果不足3个字节怎么办呢?比如,ya
或y
2、两个字节的情况处理
以ya
为例:
1、接着上面栗子第5步,将ya
的二进制串拼装到一串:0111100101100001
2、然后将0111100101100001,从左往右数,6位为一组分开,到最后一组时,显示位数不够,于是在最后一组的前面和后面分别加2个0,就变成了:011110、010110、$\color{red}{00000100}$
3、然后将这3组二进制转换成十进制数,分别是:30、22、4
4、再将上一步的3个数字,对照上面的Base64编码对照表,得到结果为:eWE,$\color{red}{这里还有一个规定:少于3个字节一组的字符串,少几个就要补几个=号}$,于是最终结果为:$\color{red}{eWE=}$
这也解释了我们平常看到了Base64编码中时常出现多个=
号的原因。
3、一个字节的情况处理
同两个字节类似处理,只是结尾多了一个 =
号
4、对汉字的处理
汉字本身可以有多种编码,比如gb2312、utf-8、gbk等等,每一种编码的Base64对应值都不一样。下面的例子以utf-8为例。
首先,“严” 字的utf-8编码为E4B8A5(如果不知道怎么查编码,点击这里,输入汉字先进行url编码,再将%去除转换成大写,就是我们需要的uft-8编码),写成二进制就是三字节的”11100100 10111000 10100101”。将这个24位的二进制字符串,按照第2节中的规则,转换成四组一共32位的二进制值”00111001 00001011 00100010 00100101”,相应的十进制数为57、11、34、37,它们对应的Base64值就为5、L、i、l。
所以,汉字”严”(utf-8编码)的Base64值就是5Lil。
三、总结
1、Base64编码,是一种编码算法,不是加密算法,主要作用是为了将二进制数据转换成文本格式。
2、Base64编码的常见的应用场景有两种:一是将图片转换成Base64编码输出到网页;二是做数字签名时,将二进制摘要数据(如PHP中hash_hmac(‘sha256’, …)函数)转换成Base64文本,见自己的另一篇文章JWT Token原理解析第三节内容。
3、Base64编码的缺点是传输效率会降低,因为它把原始数据的长度增加了1/3。
因为标准的Base64编码会出现+、/和=,所以不适合把Base64编码后的字符串放到URL中。一种针对URL的Base64编码可以在URL中使用的Base64编码,它仅仅是把+变成-,/变成_,见自己的另一篇文章JWT Token原理解析第三节内容。
参考:http://www.ruanyifeng.com/blog/2008/06/base64.html Base64编码原理