首頁>技術>

本文目的

寫這篇文章的目的主要是整理下密碼學中Base64的知識點,並把它們分享出來,並且幫助大家用自己熟悉的語言實現出來

Base64簡介

首先我需要澄清一點,Base64並不是一種加密的方法,而是一種編碼的方式。雖然用Base64加密(暫且說是加密)的字串看起來有一種被加密的感覺,但是這只是感覺。

因為如果用標準的Base64進行加密會發現很多Base64的特徵,比如在Base64字串中會出現'+'和'\\'兩種字元,在字串的末尾經常會有一個到兩個連續的'='。

只要發現了這些特徵,就可以肯定這個字串被Base64加密過,只要通過相應的解密小程式就可以輕鬆得到加密前的樣子(非標準的除外)。

那麼又為什麼說Base64是一種編碼方式呢?這是因為Base64可以把所有的二進位制資料都轉換成ASCII碼可列印字串的形式(製表符,空格等為不可列印)。以便在只支援文字的環境中也能夠順利地傳輸二進位制資料。

編碼原理

Base64編碼的核心原理是將二進位制資料進行分組,每24Bit(3位元組)為一個大組,再把一個大組的資料分成4個6Bit的小分組。

由於6Bit資料只能表示64個不同的字元(2^6=64),所以這也是Base64的名字由來。

這64個字元分別對應ASCII碼錶中的'A'-'Z','a'-'z','0''9','+'和'/'。他們的對應關係是由Base64字符集決定的。

因為小分組中的6Bit資料表示起來並不方便,所以要把每個小分組進行高位補零操作,這樣每個小分組就構成了一個8Bit(位元組)的資料。

在補零操作完成後接下來的工作就簡單多了,那就是將小分組的內容作為Base64字符集的下標,然後一一替換成對應的ASCII字元。加密工作完成。

Base64解密的工作原理也非常的簡單,只要操作方式和加密步驟相反即可。首先將Base64編碼根據其對應的字符集轉換成下標,這就是補完零後的8Bit(一位元組)資料。

既然有補零操作那自然會有去零操作了,我們要將這些8Bit資料的最高位上的兩個0抹去形成6Bit資料,這也就是前面我們提到過的小分組。

最後就是將每4個6Bit資料進行合併形成24Bit的大分組,然後將這些大分組按照每組8Bit進行拆分就會得到3個8Bit的資料,這寫8Bit資料就是加密前的資料了。解密工作完成。

重點:別看前面說的Base64工作流程這麼簡單,實際上裡面還是有很多坑的,那在我們了解了編碼原理後現在就來填坑了:

我們在Base64編碼前是無法保證準備編碼的字串長度是3的倍數,所以為了讓編碼能夠順利進行就必須在獲取編碼字串的同時判斷字串的長度是否是3的倍數。

如果是3的倍數編碼就可以正常進行,如果不是那麼就要進行額外的操作——補零,就是要在不足3的倍數的字串末尾用0x00進行填充。

這樣就是解決了字串長度不足的問題了,但是同時也引進了另一個新的問題,那就是末尾補充上的0在進行Base64字符集替換的時候會與字符集中的'A'字元發生衝突。

因為字符集中的下標0對應的字元是'A',而末尾填充上的0x00在分組補零後同樣是下標0x00,這樣就無法分辨出到底是末尾填充的0x00還是二進位制資料中的0x00。

為了解決這個問題我們就必須引入Base64字符集外的新字元來區分末尾補充上的0x00,這就是'='字元不在Base64字符集中,但是也出現在Base64編碼的原因了,'='字元在一個Base64編碼的末尾中最多會出現兩個,如果不符合這以規則那麼這個Base64就可能被人做了手腳。

Base64字符集:

Base64的編碼圖解

1、判斷字串長度,不足3的倍數用0x00填充

2、將補零後的字串進行8Bit分組

3、把每個大分組進行6Bit分組

4、將6Bit組轉換成Base64字符集的下標

5、把字符集的下標替換成Base64字元

6、修正末尾的符號,得到Base64編碼結果

解密操作和加密操作相反!

總結

寫到這裡,我對Base64演算法的理解也就分享完了。其實Base64的原理非常簡單,大家有興趣可以用自己熟悉的一門程式語言來著手實現以下。

關注大白!帶你閱讀技術書籍,了解技術內幕!

  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 介面友好的類Jira問題需求跟蹤工具——ActionView