Base64編碼原來是這么回事兒


鳴謝CSDN文章:https://blog.csdn.net/believesoul/article/details/84100616

一、言簡意賅理解Base64編碼

就是將以“字節”為單位的二進制數據,轉換為肉眼可見的64個“可打印字符”字符串的編碼方法。

啥是以“字節”為單位的二進制數據???

長得類似這個樣子:

b'C\xe8\xaf\xad\xe8\xa8\x80\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x918\xe5\xb2\x81\xe4\xba\x86' = 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\n'
base64.encodebytes(str1.encode()).decode()
'aGVsbG8gd29ybGQh\n'
base64.encodebytes(str1.encode()).decode('utf-8')
'aGVsbG8gd29ybGQh\n'

 

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+/=],不可打印字符(包括轉移字符)也可傳輸;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM