Base64 的原理、實現及應用

1、Base64編碼原理

Base64編碼是基於64個字符A-Z,a-z,0-9,+,/的編碼方式,由於2的6次方正好爲64,因此就用6bit就能夠表示出64個字符,eg:000000對應A,000001對應B。正則表達式

**BASE64 的編碼原理:**都是按字符串長度,以每 3 個 字符(1Byte=8bit)爲一組,而後針對每組,首先獲取每一個字符的 ASCII 編碼(字符'a'=97=01100001),而後將 ASCII 編碼轉換成 8 bit 的二進制,獲得一組 3 * 8=24 bit 的字節。而後再將這 24 bit 劃分爲 4 個 6 bit 的字節,並在每一個 6 bit 的字節前面都填兩個高位 0,獲得 4 個 8 bit 的字節,而後將這 4 個 8 bit 的字節轉換成十進制,對照 BASE64 編碼表 (下表),獲得對應編碼後的字符。 算法

image

注:1. 要求被編碼字符是8bit的,因此須在ASCII編碼範圍內,\u0000-\u00ff,中文就不行。   2. 若是被編碼字符長度不是3的倍數的時候,則都用0代替,對應的輸出字符爲「=」數據庫

Base64編碼本質上是一種將二進制數據轉成文本數據的方案。對於非二進制數據,是先將其轉換成二進制形式,而後每連續6比特(2的6次方=64)計算其十進制值,根據該值在A--Z,a--z,0--9,+,/ 這64個字符中找到對應的字符,最終獲得一個文本字符串。基本規則以下幾點:編程

  1. 標準Base64只有64個字符(英文大小寫、數字和+、/)以及用做後綴等號;
  2. Base64是把3個字節變成4個可打印字符,因此Base64編碼後的字符串必定能被4整除(不算用做後綴的等號);
  3. 等號必定用做後綴,且數目必定是0個、1個或2個。這是由於若是原文長度不能被3整除,Base64要在後面添加\0湊齊3n位。爲了正確還原,添加了幾個\0就加上幾個等號。顯然添加等號的數目只能是0、1或2;
  4. 嚴格來講Base64不能算是一種加密,只能說是編碼轉換。

2、Base64解碼原理

解碼原理是將4個字節轉換成3個字節.先讀入4個6位(用或運算),每次左移6位,再右移3次,每次8位,這樣就還原了。安全

3、Base64編碼字符串實例

一、字符長度爲能被3整除時:好比「Tom」 : bash

因此,「Tom」的 BASE64 編碼結果爲 VG9t。

二、字符串長度不能被3整除時,好比「Lucy」: 微信

由於4個Base編碼爲一組,最後再補上'='補齊,即:THVjeQ==

4、Base64編碼的應用

  1. 實現簡單的數據加密,使用戶一眼望去徹底看不出真實數據內容,base64算法的複雜程度要小,效率要高相對較高。網絡

  2. Base64編碼的主要的做用不在於安全性,而在於讓內容能在各個網關間無錯的傳輸,這纔是Base64編碼的核心做用。編程語言

  3. 在計算機中任何數據都是按ascii碼存儲的,而ascii碼的128~255之間的值是不可見字符。而在網絡上交換數據時,好比說從A地傳到B地,每每要通過多個路由設備,因爲不一樣的設備對字符的處理方式有一些不一樣,這樣那些不可見字符就有可能被處理錯誤,這是不利於傳輸的。因此就先把數據先作一個Base64編碼,通通變成可見字符,這樣出錯的可能性就大下降了。網站

  4. Base64 編碼在URL中的應用:

    Base64編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java持久化系統Hibernate中,就採用了Base64來將一個較長的惟一標識符(通常爲128-bit的UUID)編碼爲一個字符串,用做HTTP表單和HTTP GET URL中的參數。在其餘應用程序中,也經常須要把二進制數據編碼爲適合放在URL(包括隱藏表單域)中的形式。此時,採用Base64編碼不只比較簡短,同時也具備不可讀性,即所編碼的數據不會被人用肉眼所直接看到。

    然而,標準的Base64並不適合直接放在URL裏傳輸,由於URL編碼器會把標準Base64中的「/」和「+」字符變爲形如「%XX」的形式,而這些「%」號在存入數據庫時還須要再進行轉換,由於ANSI SQL中已將「%」號用做通配符。

    (1)爲解決此問題,可採用一種用於URL的改進Base64編碼,它不在末尾填充'='號,並將標準Base64中的「+」和「/」分別改爲了「-」和「」,這樣就免去了在URL編解碼和數據庫存儲時所要做的轉換,避免了編碼信息長度在此過程當中的增長,並統一了數據庫、表單等處對象標識符的格式。 (2)另有一種用於正則表達式的改進Base64變種,它將「+」和「/」改爲了「!」和「-」,由於「+」,「*」以及前面在IRCu中用到的「[」和「]」在正則表達式中均可能具備特殊含義。 此外還有一些變種,它們將「+/」改成「-」或「.」(用做編程語言中的標識符名稱)或「.-」(用於XML中的Nmtoken)甚至「:」(用於XML中的Name)。

    不少下載類網站都提供「迅雷下載」的連接,其地址一般是加密的迅雷專用下載地址。   如thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==   其實迅雷的「專用地址」也是用Base64加密的,其加密過程以下:

    •   1、在地址的先後分別添加AA和ZZ

    如www.baidu.com/img/sslm1_logo.gif變成 AAwww.baidu.com/img/sslm1_l…

    •   2、對新的字符串進行Base64編碼

    如AAwww.baidu.com/img/sslm1_logo.gifZZ用Base64編碼獲得QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==

    •   3、在上面獲得的字符串前加上「thunder://」就成了

    thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==

5、Base64具體實現

1. 對字符串進行Base64編碼

//對字符串進行Base64編碼
    public void base64Encode(View view) {
        String str = "a";
        stringBase64 = Base64.encodeToString(str.getBytes(), Base64.NO_PADDING);
        
        test.setText("a 的Base64編碼爲:"+stringBase64);
    }
複製代碼

2. 對字符串進行Base64解碼

//對字符串進行Base64解碼
    public void base64Decode(View view) {
        byte[] decode = Base64.decode(stringBase64, Base64.DEFAULT);
        String string = new String(decode);
        
        test.setText("base64解碼爲:"+string);
    }
複製代碼

3. 對文件進行Base64編碼

File file = new File("/storage/emulated/0/pimsecure_debug.txt");
FileInputStream inputFile = null;
try {
    inputFile = new FileInputStream(file);
    byte[] buffer = new byte[(int) file.length()];
    inputFile.read(buffer);
    inputFile.close();
    encodedString = Base64.encodeToString(buffer, Base64.DEFAULT);
    Log.e("Base64", "Base64---->" + encodedString);
} catch (Exception e) {
    e.printStackTrace();
}
複製代碼

4. 對文件進行Base64編碼

File desFile = new File("/storage/emulated/0/pimsecure_debug_1.txt");
FileOutputStream  fos = null;
try {
    byte[] decodeBytes = Base64.decode(encodedString.getBytes(), Base64.DEFAULT);
    fos = new FileOutputStream(desFile);
    fos.write(decodeBytes);
    fos.close();
} catch (Exception e) {
    e.printStackTrace();
}
複製代碼

5. 針對Base64.DEFAULT參數說明

不管是編碼仍是解碼都會有一個參數Flags,Android提供瞭如下幾種

  1. DEFAULT 這個參數是默認,使用默認的方法來加密

    對「a」進行Base64編碼結果爲:YQ==,而且編碼後出現換行符

  2. NO_PADDING 這個參數是略去加密字符串最後的」=」

    對「a」進行Base64編碼結果爲:YQ

  3. NO_WRAP 這個參數意思是略去全部的換行符(設置後CRLF就沒用了)

    對「a」進行Base64編碼結果爲:YQ==,而且編碼後不出現換行符

  4. CRLF 這個參數看起來比較眼熟,它就是Win風格的換行符,意思就是使用CR LF這一對做爲一行的結尾而不是Unix風格的LF

  5. URL_SAFE 這個參數意思是加密時不使用對URL和文件名有特殊意義的字符來做爲加密字符,具體就是以-和_取代+和/

    對「a」進行Base64編碼結果爲:YQ==,而且編碼後出現換行符

注意:BASE64Encoder每編碼76個字符後,都會在後面加上一個回車換行。因此當超過76個字符的字符串被編碼後,再解碼時會提示RuntimeError;若是除去編碼後出現的全部換行符,如使用Base64.NO_WRAP,則字符串能正常解碼。

#### YunSoul技術分享,掃碼關注微信公衆號##
    ——只要你學會了以前所不會的東西,只要今天的你強過了昨天的你,那你就一直是在進階的路上了。
相關文章
相關標籤/搜索