Base64

作者: 田心甜心 | 来源:发表于2020-10-12 17:58 被阅读0次

    Base64是什么?

    个人理解:Base64是一种编码方式,和ASCll一样,只是一种编码方式而已,但是两者用到的场景不同。
    我看到百度百科上的Base64解释上有这样一段话:

    采用Base64编码具有不可读性,需要解码后才能阅读

    总觉得‘阅读‘这个词怪怪的,在我碰到的业务场景中,列如图片的Base64化传输、秘钥密文的Base64化保存等,其原内容都不是需要人阅读的,真正的’阅读‘者都是机器。

    思考Base64产生的原因

    思考一个场景:对一段文字进行加密,并传输给服务端。

    我们一般先会将这段文字转成二进制数据,然后通过调用系统的加密算法,然后得到一串新的二进制数据,那么如何把这段二进制数据传给服务端呢?

    平时我们和服务端传输的数据基本都是utf8格式的,那么这段二进制数据能直接转成utf8格式呢?显然是不可能的,utf8的每个字节前几位的bit都是有特殊含义的(具体看utf8的生成规则),但是加密得到的二进制数据肯定输无序的,所以最好将密文的二进制数据先转成一种能被utf8编码的格式,然后就能和服务端进行utf8格式的通信了

    我们来看看平时常常提到的几种编码格式。

    先看看utf16utf32,其实他们和utf8一样,都是对Unicode码的一种编码。我们从电脑屏幕上看到的每一个字,每一个符号,甚至有些表情都对应一个Unicode码,那么可以用Unicode码编码密文二进制数据么?答案是不可以。拿utf32举例,它其实就是用4个字节表示一个Unicode码,但4个字节有多少种组合呢?2^{(4*8)}种,Unicode码的个数只是其中的一部分,但是Unicode码并不是固定的,它每年还在增加。如果密文数据正好落在Unicode码没有的地方,系统就展示不出来了。而且如果真有一段密文用utf16展示,里面出现了英文、中文、韩文、数学符号、表情等,你会不会疯掉(手动滑稽)

    ASCll码表示,似乎是一个很好的注意,因为ASCll码已经排满,能做到二进制和符号一一对应的关系。但为什么不可以呢,或者说有什么不方便呢?一方面ASCll码中有许多特殊字符,列如'"\等等,在展示的时候,有些地方需要加转义符,有些地方不需要添加,会比较混乱。另一方面ASCll码排在前面的一些位置并不是符号能展示出来,列如7号位的响铃。

    其实到这里离Base64的产生已经很接近了。如果我们把ASCll码中那些不能展示出来的位置,和一些特殊字符的位置去掉,形成一种新的编码,那就能很好的展示出密文内容了。基础的ASCll码占7个bit位,如果去掉一些,那新的编码格式就用6个bit位好了,2^6 = 64Base64就应运而生了。

    当然,上面都是我个人的理解。Base64算法主要最早用于解决电子邮件传输问题。在早期,由于历史问题,电子邮件只允许传输ASCII码字符。当传输非ASCII码时,网关很可能将非ASCII码的二进制位调整,即将非ASCII码的8位二进制的最高位设为0。当用户收到邮件时,可想而知,收到的就是 一份乱码的邮件。

    Base64的规则

    所谓的Base64,就是64个符号来表示6个bit位的二进制流。这64个符号分别为a-z,A-Z,0-9及+/。这里有张对照表

    索引 符号 索引 符号 索引 符号 索引 符号
    0 A 16 Q 32 g 48 w
    1 B 17 R 33 h 49 x
    2 C 18 S 34 i 50 y
    3 D 19 T 35 j 51 z
    4 E 20 U 36 k 52 0
    5 F 21 V 37 l 53 1
    6 G 22 W 38 m 54 2
    7 H 23 X 39 n 55 3
    8 I 24 Y 40 o 56 4
    9 J 25 Z 41 p 57 5
    10 K 26 a 42 q 58 6
    11 L 27 b 43 r 59 7
    12 M 28 c 44 s 60 8
    13 N 29 d 45 t 61 9
    14 O 30 e 46 u 62 +
    15 P 31 f 47 v 63 /

    具体来说,转换方式可以分为四步。

    • 第一步,将每三个字节作为一组,一共是24个二进制位。
    • 第二步,将这24个二进制位分为四组,每个组有6个二进制位。
    • 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。
    • 第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。

    举一个具体的实例,演示英语单词Man如何转成Base64编码。


    image.png
    • 第一步,"M"、"a"、"n"的ASCII值分别是77、97、110,对应的二进制值是01001101、01100001、01101110,将它们连成一个24位的二进制字符串010011010110000101101110。
    • 第二步,将这个24位的二进制字符串分成4组,每组6个二进制位:010011、010110、000101、101110。
    • 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节:00010011、00010110、00000101、00101110。它们的十进制值分别是19、22、5、46。
    • 第四步,根据上表,得到每个值对应Base64编码,即T、W、F、u。

    因此,Man的Base64编码就是TWFu。

    如果字节数不足三,则这样处理:

    • 二个字节的情况:将这二个字节的一共16个二进制位,按照上面的规则,转成三组,最后一组除了前面加两个0以外,后面也要加两个0。这样得到一个三位的Base64编码,再在末尾补上一个"="号。
      比如,"Ma"这个字符串是两个字节,可以转化成三组00010011、00010110、00010000以后,对应Base64值分别为T、W、E,再补上一个"="号,因此"Ma"的Base64编码就是TWE=。
    • 一个字节的情况:将这一个字节的8个二进制位,按照上面的规则转成二组,最后一组除了前面加二个0以外,后面再加4个0。这样得到一个二位的Base64编码,再在末尾补上两个"="号。
      比如,"M"这个字母是一个字节,可以转化为二组00010011、00010000,对应的Base64值分别为T、Q,再补上二个"="号,因此"M"的Base64编码就是TQ==。

    相关文章

      网友评论

          本文标题:Base64

          本文链接:https://www.haomeiwen.com/subject/zhwupktx.html