zoukankan      html  css  js  c++  java
  • Base64编码原来是这么回事儿

    鸣谢CSDN文章:https://blog.csdn.net/believesoul/article/details/84100616

    一、言简意赅理解Base64编码

    就是将以“字节”为单位的二进制数据,转换为肉眼可见的64个“可打印字符”字符串的编码方法。

    啥是以“字节”为单位的二进制数据???

    长得类似这个样子:

    b'Cxe8xafxadxe8xa8x80xe4xb8xadxe6x96x87xe7xbdx918xe5xb2x81xe4xbax86' = bytes('C语言中文网8岁了', encoding='UTF-8')
    详见:https://www.cnblogs.com/zhangmingda/p/14123752.html

    二、为啥要做编码转换?

    答:一般用于在HTTP协议下传输二进制数据,由于HTTP协议是文本协议,所以在HTTP协议下传输二进制数据需要将二进制数据转换为字符数据。然而直接转换是不行的。因为网络传输只能传输可打印字符。

    这玩意只是编码,不是加密,但是肉眼看不出原始内容

    三、转换为哪64个可打印字符?

    答:是ASCII码里面95个可打印字符中筛选出了64个:即后面括号内 [0-9a-zA-Z+/=]  即数字0到9,大小写字母 和 +/= 实际为65个可打印字符。

    具体什么是可打印字符?在ASCII码中规定,0-31、128这33个字符属于控制字符,32-127这95个字符属于可打印字符,也就是说网络传输只能传输这95个字符,不在这个范围内的字符无法传输。那么该怎么才能传输其他字符呢?其中一种方式就是使用Base64。

    Base64,就是使用64个可打印字符来表示二进制数据的方法。这64个字符中包括大小写字母、数字、+和/,还有用来补缺的特殊字符=。

    注意:由于base64编码用了8位字符来表示信息中的6个位,所以base64编码字符串大约比原始值扩大了33%。

    Base64的索引与对应字符的关系如下表所示:
    在这里插入图片描述
    也就是说,如果将索引转换为对应的二进制数据的话需要至多6个Bit。然而ASCII码需要8个Bit来表示,那么怎么使用6个Bit来表示8个Bit的数据呢?6个Bit当然不能存储8个Bit的数据,但是4×6个Bit可以存储3×8个Bit的数据啊!如下表所示:
    在这里插入图片描述

    可以看到“Son”通过Base64编码转换成了“U29u”。这是刚刚好的情况,3个ASCII字符刚好转换成对应的4个Base64字符。但是,当需要转换的字符数不是3的倍数的情况下该怎么办呢?Base64规定,当需要转换的字符不是3的倍数时,一律采用补0的方式凑足3的倍数,具体如下表所示:
    在这里插入图片描述

    每6个Bit为一组,第一组转换后为字符“U”,第二组末尾补4个0转换后为字符“w”。剩下的使用“=”替代。即字符“S”通过Base64编码后为“Uw==”。这就是Base64的编码过程。

    如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。

    这是字节的位总数不是6的倍数的情况,当剩下4位时,我们需要补2个=凑齐8的倍数;当剩下的是2位时,我们需要补齐1个 = 抽泣8的倍数。
    补全机制

    四、Base64怎么用?

    Python3计算Base64

    import base64
    str1 = "hello world!"
    base64.encodebytes(str1.encode())
    b'aGVsbG8gd29ybGQh
    '
    base64.encodebytes(str1.encode()).decode()
    'aGVsbG8gd29ybGQh
    '
    base64.encodebytes(str1.encode()).decode('utf-8')
    'aGVsbG8gd29ybGQh
    '

    Java计算Base64,使用的时候直接调用内部模块即可。具体代码如下所示:

    package com.first;
     
    import org.junit.Test;
     
    import java.io.UnsupportedEncodingException;
    import java.util.Base64;
     
    public class Test {
     
        @Test
        public void test() throws UnsupportedEncodingException {
            // 编码
            String encode = Base64.getEncoder().encodeToString("So".getBytes("UTF-8"));
            System.out.println(encode);
            // 解码
            byte[] decode = Base64.getDecoder().decode(encode);
            System.out.println(new String(decode, "UTF-8"));
        }
     
    }

    五、Base64的相关点

    1. 首先这算法是编码,不是压缩,编码后只会增加字节数;字节数会成为原字节数的4/3;
    2. 算法简单, 几乎不会影响效率;
    3. 算法可逆, 解码很方便, 不用于私密信息通信;
    4. 虽然解码方便, 但毕竟编码了, 肉眼还是不能直接看出原始内容;
    5. 加密后的字符串只有[0-9a-zA-Z+/=],不可打印字符(包括转移字符)也可传输;
  • 相关阅读:
    【Henu ACM Round#17 A】Simple Game
    【Henu ACM Round #12 E】Thief in a Shop
    【Henu ACM Round#16 D】Bear and Two Paths
    【Henu ACM Round#16 A】 Bear and Game
    P4824 [USACO15FEB]Censoring (Silver) 审查(银)
    P4001 [BJOI2006]狼抓兔子
    P2444 [POI2000]病毒
    P3966 [TJOI2013]单词
    P3796 【模板】AC自动机
    P4574 [CQOI2013]二进制A+B
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/14124282.html
Copyright © 2011-2022 走看看