• Base64编码原理分析


    之前看到了Base64编码,但是对其原理一直模模糊糊,不大明白,今天决定要搞懂了!

    先上图:

    image

    其实,我没怎么看懂,008B5DCB

    百度了下,从头开始解释:

    一、计算机容量单位及单位换算

    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(进制)方法,转成相应的进制:

    比方说:

    image

    + 的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
    97  01100001

    所以字符 a:a 用二进制表示就是  011000010011101001100001

    按照Base64编码规则,我们要把 011000010011101001100001,拆成4组,每组6位,那就是 011000 010011 101001 100001,把他们转成10进制,就是24 19 41 33,可能有人问,怎么把2进制,转为10进制呢?

    在js里,就是,parseInt(字符串,进制);上面的四组就是:

    image

    然后根据下面的Base64字母表,就可以得出,24 19 41 33,分别为 Y T p h;所以 a:a 按照Base64编码结果为 YTph,明白了么?

    image

    说到这里呢,其实还没完,前面应该有人已经想到了,如果一个字符串的长度不是3的n倍个字节呢?嗯嗯,比如4个字节?如 :

    a:aa

    呐,咱们照例,先把每个字节转成ASCII码,然后转成二进制,就是:

    字符 ASCII码(10进制) 二进制(不足8位高位补0)
    a 97    01100001
    : 58    00111010
    97  01100001
    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

    image

    对照Base-64字母表,就是 Q,

    综上,

    a:aa  经过Base64编码结果就为  YTphYQ

    这,就是Base64编码原理,解码就反向而行!

    不过,在js里,本身提供了Base64编码解码的方法,还是以上面 a:aa 为例,就是

    image

  • 相关阅读:
    Java内存模型之从JMM角度分析DCL
    MySQL系列(九)--InnoDB索引原理
    MySQL系列(一)--基础知识(转载)
    MySQL系列(八)--数据库分库分表
    MySQL系列(七)--SQL优化的步骤
    MySQL系列(六)--索引优化
    MySQL系列(五)--二进制日志对主从复制的影响
    Java集合(七)--基于jdk1.8的HashMap源码
    Java数据结构和算法(八)--红黑树与2-3树
    Java数据结构和算法(七)--AVL树
  • 原文地址:https://www.cnblogs.com/xianshenglu/p/8401150.html
Copyright © 2020-2023  润新知