一、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 編碼表 (下表),得到對應編碼後的字元。
注:1. 要求被編碼字元是8bit的,所以須在ASCII編碼範圍內,\u0000-\u00ff,中文就不行。 2. 如果被編碼字元長度不是3的倍數的時候,則都用0代替,對應的輸出字元為“=”
Base64編碼本質上是一種將二進位制資料轉成文字資料的方案。對於非二進位制資料,是先將其轉換成二進位制形式,然後每連續6位元(2的6次方=64)計算其十進位制值,根據該值在A--Z,a--z,0--9,+,/ 這64個字元中找到對應的字元,最終得到一個文字字串。基本規則如下幾點:
- 標準Base64只有64個字元(英文大小寫、數字和+、/)以及用作字尾等號;
- Base64是把3個位元組變成4個可列印字元,所以Base64編碼後的字串一定能被4整除(不算用作字尾的等號);
- 等號一定用作字尾,且數目一定是0個、1個或2個。這是因為如果原文長度不能被3整除,Base64要在後面新增\0湊齊3n位。為了正確還原,新增了幾個\0就加上幾個等號。顯然新增等號的數目只能是0、1或2;
- 嚴格來說Base64不能算是一種加密,只能說是編碼轉換。
二、Base64解碼原理
解碼原理是將4個位元組轉換成3個位元組.先讀入4個6位(用或運算),每次左移6位,再右移3次,每次8位,這樣就還原了。
三、Base64編碼字串例項
1、字元長度為能被3整除時:比如“Tom” :
所以,“Tom”的 BASE64 編碼結果為 VG9t。2、字串長度不能被3整除時,比如“Lucy”:
因為4個Base編碼為一組,最後再補上'='補齊,即:THVjeQ==四、Base64編碼的應用
-
實現簡單的資料加密,使使用者一眼望去完全看不出真實資料內容,base64演算法的複雜程度要小,效率要高相對較高。
-
Base64編碼的主要的作用不在於安全性,而在於讓內容能在各個閘道器間無錯的傳輸,這才是Base64編碼的核心作用。
-
在計算機中任何資料都是按ascii碼儲存的,而ascii碼的128~255之間的值是不可見字元。而在網路上交換資料時,比如說從A地傳到B地,往往要經過多個路由裝置,由於不同的裝置對字元的處理方式有一些不同,這樣那些不可見字元就有可能被處理錯誤,這是不利於傳輸的。所以就先把資料先做一個Base64編碼,統統變成可見字元,這樣出錯的可能性就大降低了。
-
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加密的,其加密過程如下:
- 一、在地址的前後分別新增AA和ZZ
如www.baidu.com/img/sslm1_logo.gif變成 AAwww.baidu.com/img/sslm1_l…
- 二、對新的字串進行Base64編碼
- 三、在上面得到的字串前加上“thunder://”就成了
thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
五、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提供了以下幾種
-
DEFAULT 這個引數是預設,使用預設的方法來加密
對“a”進行Base64編碼結果為:YQ==,並且編碼後出現換行符
-
NO_PADDING 這個引數是略去加密字串最後的”=”
對“a”進行Base64編碼結果為:YQ
-
NO_WRAP 這個引數意思是略去所有的換行符(設定後CRLF就沒用了)
對“a”進行Base64編碼結果為:YQ==,並且編碼後不出現換行符
-
CRLF 這個引數看起來比較眼熟,它就是Win風格的換行符,意思就是使用CR LF這一對作為一行的結尾而不是Unix風格的LF
-
URL_SAFE 這個引數意思是加密時不使用對URL和檔名有特殊意義的字元來作為加密字元,具體就是以-和_取代+和/
對“a”進行Base64編碼結果為:YQ==,並且編碼後出現換行符
注意:BASE64Encoder每編碼76個字元後,都會在後面加上一個回車換行。所以當超過76個字元的字串被編碼後,再解碼時會提示RuntimeError;如果除去編碼後出現的所有換行符,如使用Base64.NO_WRAP,則字串能正常解碼。
#### YunSoul技術分享,掃碼關注微信公眾號##
-
——只要你學會了之前所不會的東西,只要今天的你強過了昨天的你,那你就一直是在進階的路上了。