什麼是Base64?什麼時候使用?編碼原理?優缺點?Java程式碼例項?
**
1.什麼是Base64?
** Base64是網路上最常見的用於傳輸8Bit位元組碼的編碼方式之一,Base64就是一種基於64個可列印字元來標識二進位制資料的方法。 Base64是一種可逆的編碼方式,是一種用64個Ascii字元來表示任意二進位制資料的方法。 主要用於將不可列印字元轉換為可列印字元,或者簡單的說將二進位制資料編碼為Ascii字元, **
2.什麼時候使用Base64?
** 1.Base64一般用於在HTTP協議下傳輸二進位制資料,由於HTTP協議是文字協議,所以在HTTP寫一下傳輸二進位制資料需要將二進位制資料轉化為字元資料, 網路傳輸只能傳輸可列印字元, 在ASCII碼中規定,0-31、128這33個字元屬於控制字元, 32~127這95個字元屬於可列印字元 那麼其它字元怎麼傳輸呢,Base64就是其中一種方式, 2.將圖片等資原始檔以Base64編碼形式直接放於程式碼中,使用的時候反Base64後轉換成Image物件使用。 3.偶爾需要用這條純文字通道傳一張圖片之類的情況發生的時候,就會用到Base64,比如多功能Internet 郵件擴充服務(MIME)就是用Base64對郵件的附件進行編碼的。 **
3.編碼原理。
** Base64,就是使用64個可列印字元來表示二進位制資料的方法。Base64的索引與對應字元的關係如下表所示:0~63分別對應了唯一一個字元,比如18對應的是S。 對二進位制資料進行處理,每3個位元組一組,一共3x8=24bit,將這24bit劃分為4組,每組正好6個bit,6bit的資料剛好可以表示0~63的範圍,也就可以對應上表的64個字元。這樣我們就得到了4個數字作為索引,然後查表獲得相應的4個字元,就得到了編碼後的字串。 所以,Base64編碼會把3位元組的二進位制資料編碼為4位元組的文字資料,長度增加為原來的4/3。如果要編碼的二進位制資料不是3的倍數,最後會剩下1個或2個位元組怎麼辦?此時,需在原資料後面新增1個或2個零值位元組,使其位元組數是3的倍數。然後,在編碼後的字串後面新增1個或2個等號“=”,表示所新增的零值位元組數。解碼的時候,會自動去掉。 **
4.優缺點
** 優點:可以將二進位制資料轉化為可列印字元,方便傳輸資料,對資料進行簡單的加密,肉眼安全。 缺點:內容編碼後體積變大,編碼和解碼需要額外工作量。 **
5.java程式碼
**
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")); } }
**
6.獲取pdf位元組流轉換為字串傳輸,在獲取字串轉位元組流生成pdf例項
**
package pandaLearnIOStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import org.bouncycastle.util.encoders.Base64;
public class BytesExample {
public static void main(String[] args) {
try {
/*
* 客戶端把檔案轉換成二進位制字串, 得到的是一個string, 通過介面傳輸
*/
byte[] out = readFileInBytesToString("D:\\from\\180726-測試.docx");//獲取位元組流檔案的路徑
System.out.println("====檔案二進位制字串====="+new String(out,"ISO-8859-1"));
String fileString = new String(out,"ISO-8859-1");
/*
* 伺服器獲取到字串後, 反寫二進位制, 得到檔案。
*/
File outfile = new File("D:\\fromto\\180726-測試_3.docx");
if (!outfile.exists()) {
outfile.createNewFile();
}
DataOutputStream fw = new DataOutputStream(new FileOutputStream(outfile));
fw.write(new Base64().decode(fileString.getBytes("ISO-8859-1")));//解碼-解密
fw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] readFileInBytesToString(String filePath) {
final int readArraySizePerRead = 4096;
File file = new File(filePath);
ArrayList<Byte> bytes = new ArrayList<Byte>();
try {
if (file.exists()) {
DataInputStream isr = new DataInputStream(new FileInputStream(file));
byte[] tempchars = new byte[readArraySizePerRead];
int charsReadCount = 0;
while ((charsReadCount = isr.read(tempchars)) != -1) {
for(int i = 0 ; i < charsReadCount ; i++){
bytes.add (tempchars[i]);
}
}
isr.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return toPrimitives(bytes.toArray(new Byte[0]));
}
static byte[] toPrimitives(Byte[] oBytes) {
byte[] bytes = new byte[oBytes.length];
for (int i = 0; i < oBytes.length; i++) {
bytes[i] = oBytes[i];
}
bytes = new Base64().encode(bytes);//編碼-加密
return bytes;
}
}