開發中Base64編碼運用

一.Base64編碼原理Base64是網絡上最常見的用於傳輸8Bit字節碼的編碼方式之一,其編碼原理如下:

1. 統計需要編輯的字符串長度,把需要編譯的字符串按每3個爲一組,長度整除3的在字符串後面加0補全,最終把字符串分爲若干組

2. 編碼時以組爲單位,組中的字符串轉爲ASCII編碼,得到3個ASCII編碼數字,再把3個ASCII編碼數字轉爲8bit字節的二進制,一共得到24個字節

3. 再把24個字節分爲4組,每組爲6bit字節的二進制,把每一組的二進制轉爲十進制

4. 根據Base64編碼表對數據進行編碼,得到Base64編碼。Base64編碼表如下



Base64 編碼表
Value Char   Value Char   Value Char   Value Char
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

Base64編碼舉例:

a)字符串(bat),長度爲3,能夠被3整除,base64編碼後結果爲:YmF0;其編碼過程如下:

原始字符 b a t  
ASCII:  62 61 74  
8bit字節: 01100010 01100001 01110100  
6bit字節: 011000 100110 000101 110100
十進制:    24 38 5 52
對應編碼:   Y m F 0


b)字符串(eakom),長度爲5,不能被3整除,編碼是需要在後面補0,base64編碼後結果爲:ZWFrb20=;其編碼過程如下:

原始字符 e a k   o m    
ASCII:  101 97 107   111 109    
8bit字節: 1100101 01100001 01101011   01101111 01101101 00000000  
6bit字節: 11001 010110 000101 101011 011011 110110 110100 000000
十進制:    25 22 5 43 27 54 52 0
對應編碼:   Z W F r b 2 0 =

編碼說明:把3個8位字節(3*8=24)轉化爲4個6位的字節(4*6=24),之後在6位的前面補兩個0,形成8位一個字節的形式。 如果剩下的字符不足3個字節,則用0填充,輸出字符使用'=',因此編碼後輸出的文本末尾可能會出現1或2個'='。
二、base64運用場景

a)用於URL中,迅雷下載和百度雲盤分析的URL鏈接大部分使用Base64編譯

b)嵌入Css文件中直接顯示圖片

#fkbx-spch, #fkbx-hspch {
  background: url(data:image/gif;base64,R0lGODlhHAAmAKIHAKqqqsvLy0hISObm5vf394uLiwAAAP///yH5B…EoqQqJKAIBaQOVKHAXr3t7txgBjboSvB8EpLoFZywOAo3LFE5lYs/QW9LT1TRk1V7S2xYJADs=) no-repeat center;
}

c)HTML中嵌入base64編碼,瀏覽器解析Base64編碼顯示圖片

<img src="data:image/gif;base64,R0lGODlhHAAmAKIHAKqqqsvLy0hISObm5vf394uLiwAAAP///yH5B…EoqQqJKAIBaQOVKHAXr3t7txgBjboSvB8EpLoFZywOAo3LFE5lYs/QW9LT1TRk1V7S2xYJADs=">

三、Java常用的Base64編碼轉換

package com.eakom.common.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.bouncycastle.util.encoders.UrlBase64;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
 * Base二進制文件處理類
 * @author eakom
 * @date 2017年5月26日
 */
public class Base64Utils {
	private Base64Utils(){
	}
	private static final Logger logger=LoggerFactory.getLogger(Base64Utils.class );
	public final static String ENCODING="UTF-8"; 
	
	/**
	 * base64轉字符串
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String Base642String(String str) throws UnsupportedEncodingException {
		byte[] bytes = Base64.decodeBase64(str.getBytes());
		return new String(bytes);
	}

	/**
	 * 字符串轉base64編碼
	 * 
	 * @param str
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String String2Base64(String str) throws UnsupportedEncodingException {
		byte[] bytes = Base64.encodeBase64(str.getBytes());
		return new String(bytes);
	}
	/**
	 * 將string類型的數據轉碼爲byte類型.
	 * 
	 * @param fileData
	 *            String 類型的數據.
	 * @return 轉碼後的數據byte類型,發生異常或者filedate爲null或者“”時返回空byte[0].
	 */
	public static byte[] String2byte(String fileData) {
		if (fileData != null&&!"".equals(fileData)) {
			BASE64Decoder decoder = new BASE64Decoder();
			try {
				return decoder.decodeBuffer(fileData);
			} catch (IOException e) {
				logger.error("String2byte出錯", e);
			}
		}
		return new byte[0];
	}
	/**
	 * 將byte類型的數據經過base64編碼轉爲string.
	 * @param fileData
	 *            byte類型的數據 .
	 * @return 轉碼後的數據,發生異常或者filedate爲null時返回空"".
	 */
	public static String byte2String(byte[] fileData) {
		if (fileData != null) {
			BASE64Encoder encoder = new BASE64Encoder();
			return encoder.encode(fileData).replaceAll("\\s*","");
		}
		return "";
	}
	/**
	 * 將對象編碼爲base64的String.
	 * 
	 * @param object
	 *            要進行編碼的對象.
	 * @return 編碼後的對象對應的bease64String.
	 */
	public static String Object2Base64(Object object) {
		String objectString = null;
		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
		try {
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(
					arrayOutputStream);
			objectOutputStream.writeObject(object);
			objectString = byte2String(arrayOutputStream
					.toByteArray());
		} catch (IOException e) {
			logger.error("Object2Base64出錯", e);
		}
		return objectString;
	}

	/**
	 * 將bease64的String解編碼爲對象;
	 * 
	 * @param objectString
	 *            可以解編碼爲Object的Base64String,如果不能解編碼爲Object拋出異常.
	 * @return 解編碼成功後的對象.
	 */
	public static Object Base642Object(String objectString) {
		Object object = null;
		ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
				String2byte(objectString));
		try {
			ObjectInputStream objectInputStream = new ObjectInputStream(
					byteArrayInputStream);
			object = objectInputStream.readObject();
		} catch (IOException e) {
			logger.error("Base642Object", e);
		} catch (ClassNotFoundException e) {
			logger.error("Object2Base64路徑錯誤出錯", e);
		}
		return object;
	}
	/**
	 * 將InputStream類型的數據轉碼爲String.
	 * 
	 * @param fileData
	 *            InputStream類型的數據.
	 * @return 轉碼後的數據String類型,發生異常或者filedate爲null時返回null.
	 */
	public static String InputStream2String(InputStream fileData) {
		if (fileData == null) {
			return null;
		}
		BASE64Encoder encoder = new BASE64Encoder();
		byte[] _fileData;
		try {
			_fileData = new byte[fileData.available()];
			fileData.read(_fileData);
			fileData.close();
			return encoder.encode(_fileData).replaceAll("\\s*","");
		} catch (IOException e) {
			logger.error("InputStream2String出錯", e);
		}
		return null;
	}
	/**
	 * Base64轉InputStream
	 * @param data 
	 * @return
	 */
	public static InputStream Base642InputStream(String base64){
		BASE64Decoder decoder = new BASE64Decoder();
		InputStream is=null;
		try {
			// 解密
			byte[] b = decoder.decodeBuffer(base64);
			// 處理數據
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {
				b[i] += 256;
				}
			}
		is = new ByteArrayInputStream(b); 
		}catch(IOException e){
			logger.error("Base642InputStream", e);
		}
		return is;
	}
	/**
	 * 加密
	 * @param data
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String encoded(String data) throws UnsupportedEncodingException{
		byte[] b=UrlBase64.encode(data.getBytes(ENCODING));
		return new String(b,ENCODING);
	}
	/**
	 * 解密
	 * @param data
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String decode(String data) throws UnsupportedEncodingException{
		byte[] b=UrlBase64.decode(data.getBytes(ENCODING));
		return new String(b,ENCODING);
	}
	/**
	* @Description: 將base64編碼字符串轉換爲圖片
	* @Author: 
	* @CreateTime: 
	* @param imgStr base64編碼字符串
	* @param path 圖片路徑-具體到文件
	* @return
	*/
	public static boolean Base642Image(String imgStr, String path) {
		if (imgStr == null){		
			return false;
		}
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			// 解密
			byte[] b = decoder.decodeBuffer(imgStr);
			// 處理數據
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {
				b[i] += 256;
				}
			}
			OutputStream out = new FileOutputStream(path);
			out.write(b);
			out.flush();
			out.close();
			return true;
		} catch (Exception e) {
			logger.error("Base642Image異常", e);
			return false;
		}
	}
	/**
	 * @Description: 根據圖片地址轉換爲base64編碼字符串
	 * @Author: 
	 * @CreateTime: 
	 * @return
	 */
	public static String Image2Base64(String imgFile) {
	    InputStream inputStream = null;
	    byte[] data = null;
	    try {
	        inputStream = new FileInputStream(imgFile);
	        data = new byte[inputStream.available()];
	        inputStream.read(data);
	        inputStream.close();
	    } catch (IOException e) {
	    	logger.error("Image2Base64出錯", e);
	    }
	    // 加密
	    BASE64Encoder encoder = new BASE64Encoder();
	    return encoder.encode(data);
	}
	public static void main(String[] args) throws UnsupportedEncodingException {
		String image2String = Image2Base64("D:/二維碼-1497779927202.png");
		String imgStr="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";
		String path="D:/1234125.jpg";
		Base642Image(imgStr, path);
		System.out.println(image2String);
	}
}


四、base64編碼後文件大小比之前的文件大了1/4,不利於保存;嵌入css中的base64編碼圖片會增加瀏覽器渲染的壓力,因此只適合嵌入一些小圖片,不適合把大圖片嵌入其中。Base64主要在一些特殊情況下處理圖片或PDF文件,其他地方慎重使用。

Base64 編碼表
Value Char   Value Char   Value Char   Value Char
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章