Base64编码原理分析
之前看到了Base64编码,但是对其原理一直模模糊糊,不大明白,今天决定要搞懂了!
先上图:
百度了下,从头开始解释:
一、计算机容量单位及单位换算
1、b(又称:bit,位),是计算机中最小的单位,有两个值:0,1;
注意:但这个b和大写B的不是一个单位。
2、B(又称:Byte,字节)是计算机中最基本的计量单位。
两者的关系:1B=8b,一个字节=8个位
二、编码问题
1. ASCII码
在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。
上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。
ASCII码一共规定了128个字符的编码,比如空格"SPACE"是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。
就目前来说,英语大小写字母,0-9数字和 + /,总共64个字符,都可以用ASCII码来表示;
就js来说,可以用charCodeAt()方法求字符的ASCII码,不过是10进制,然后可以用toString(进制)方法,转成相应的进制:
比方说:
+ 的ASCII码为43,转成2进制为 101011,这里2进制不足8位,前面补0就是:00101011。
所以,英语大小写字母,0-9数字和 + /,总共64个字符,都可以用ASCII码来表示,进一步,都可以表示成 8 位二进制。
三、Base64编码
Base64编码,就是将,三个字节(也就是3*8=24位)的数据,变成6个bit为一组的组集,也就是4组*6位,还是24位;既然每组只有6位,所以最多只能表示64个数,从000000到111111;而这64个数就是,52个大小写字母、10个数字0-9、+、/。
举个例子:字符串 a:a ,总共3个字节,每个字节用二进制表示分别为,
字符 | ASCII码(10进制) | 二进制(不足8位高位补0) |
a | 97 | 01100001 |
: | 58 | 00111010 |
a | 97 | 01100001 |
所以字符 a:a 用二进制表示就是 011000010011101001100001
按照Base64编码规则,我们要把 011000010011101001100001,拆成4组,每组6位,那就是 011000 010011 101001 100001,把他们转成10进制,就是24 19 41 33,可能有人问,怎么把2进制,转为10进制呢?
在js里,就是,parseInt(字符串,进制);上面的四组就是:
然后根据下面的Base64字母表,就可以得出,24 19 41 33,分别为 Y T p h;所以 a:a 按照Base64编码结果为 YTph,明白了么?
说到这里呢,其实还没完,前面应该有人已经想到了,如果一个字符串的长度不是3的n倍个字节呢?嗯嗯,比如4个字节?如 :
a:aa
呐,咱们照例,先把每个字节转成ASCII码,然后转成二进制,就是:
字符 | ASCII码(10进制) | 二进制(不足8位高位补0) |
a | 97 | 01100001 |
: | 58 | 00111010 |
a | 97 | 01100001 |
a | 97 | 01100001 |
放在一起就是:
01100001001110100110000101100001
然后每3个字节,也就是24位,按照Base64编码规则,每组6位,这里有3*8+1*8就是32位,所以就是,5组+2位,就是下面这样:
011000 010011 101001 100001 011000 01
但是,Base64编码是每3个字节一转,也就是每24位一转,不足24位的就在序列末尾填充零位,补到长度为24的倍数为止,像上面总共32位,所以要补到48位,就是这样:
011000 010011 101001 100001 011000 01xxxx xxxxxx xxxxxx
注意:补充位以x表示;
按照Base64编码规则,
对已填充的二进制串进行编码时,任何完全填充(不包含原始数据中的位)的6 位组都由特殊的第65 个符号“=”表示。如果6 位组是部分填充的,就将填充位设置为0。
因此上面的48位二进制实际就是:
011000 010011 101001 100001 011000 01xxxx ==
对吧?咱们逐个解密(每组先转成10进制,然后对照Base-64字母表查)就是:
Y T p h Y 01xxxx ==
这里咱们就遇到问题了,01xxxx 这个怎么转?把x当成0么?对!就是这样!
所以 01xxxx 就是 010000 ,也就是10进制的,16
对照Base-64字母表,就是 Q,
综上,
a:aa 经过Base64编码结果就为 YTphYQ
这,就是Base64编码原理,解码就反向而行!
不过,在js里,本身提供了Base64编码解码的方法,还是以上面 a:aa 为例,就是
行文仓促,如有错误,欢迎批评指正~~~
转载请注明来源,文中所提文档可以在我的 Github 上下载~~~新博客现已迁移至 Github issues