一、Base64編碼由來
為什么會有Base64編碼呢?因?yàn)橛行┚W(wǎng)絡(luò)傳送渠道并不支持所有的字節(jié),例如傳統(tǒng)的郵件只支持可見字符的傳送,像ASCII碼的控制字符就 不能通過郵件傳送。這樣用途就受到了很大的限制,比如圖片二進(jìn)制流的每個(gè)字節(jié)不可能全部是可見字符,所以就傳送不了。最好的方法就是在不改變傳統(tǒng)協(xié)議的情 況下,做一種擴(kuò)展方案來支持二進(jìn)制文件的傳送。把不可打印的字符也能用可打印字符來表示,問題就解決了。Base64編碼應(yīng)運(yùn)而生,Base64就是一種 基于64個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的表示方法。
二、Base的索引表
看一下Base64的索引表,字符選用了"A-Z、a-z、0-9、+、/" 64個(gè)可打印字符。數(shù)值代表字符的索引,這個(gè)是標(biāo)準(zhǔn)Base64協(xié)議規(guī)定的,不能更改。

三、Base64的原理
Base64的碼表只有64個(gè)字符, 如果要表達(dá)64個(gè)字符的話,使用6的bit即可完全表示(2的6次方為64)。
因?yàn)锽ase64的編碼只有6個(gè)bit即可表示,而正常的字符是使用8個(gè)bit表示, 8和6的最小公倍數(shù)是24,所以4個(gè)Base64字符可以表示3個(gè)標(biāo)準(zhǔn)的ascll字符;
如果是字符串轉(zhuǎn)換為Base64碼, 會先把對應(yīng)的字符串轉(zhuǎn)換為ascll碼表對應(yīng)的數(shù)字, 然后再把數(shù)字轉(zhuǎn)換為2進(jìn)制, 比如a的ascll碼味97, 97的二進(jìn)制是:01100001, 把8個(gè)二進(jìn)制提取成6個(gè),剩下的2個(gè)二進(jìn)制和后面的二進(jìn)制繼續(xù)拼接, 最后再把6個(gè)二進(jìn)制碼轉(zhuǎn)換為Base64對于的編碼, 以下為具體的解析過程案例:

現(xiàn)在還有一點(diǎn)小問題,當(dāng)轉(zhuǎn)換到最后, 最后的字符不足3個(gè)字符咋辦, 如果不足三個(gè)字符的話,我們直接在最后添加=號即可, 具體可以參考以下兩個(gè)字符串轉(zhuǎn)換案例:

四、總結(jié)
說起B(yǎng)ase64編碼可能有些奇怪,因?yàn)榇蠖鄶?shù)的編碼都是由字符轉(zhuǎn)化成二進(jìn)制的過程,而從二進(jìn)制轉(zhuǎn)成字符的過程稱為解碼。而Base64的概念就恰好反了,由二進(jìn)制轉(zhuǎn)到字符稱為編碼,由字符到二進(jìn)制稱為解碼。
Base64編碼主要用在傳輸、存儲、表示二進(jìn)制等領(lǐng)域,還可以用來加密,但是這種加密比較簡單,只是一眼看上去不知道什么內(nèi)容罷了,當(dāng)然也可以對Base64的字符序列進(jìn)行定制來進(jìn)行加密。
Base64編碼是從二進(jìn)制到字符的過程,像一些中文字符用不同的編碼轉(zhuǎn)為二 進(jìn)制時(shí),產(chǎn)生的二進(jìn)制是不一樣的,所以最終產(chǎn)生的Base64字符也不一樣。例如"上網(wǎng)"對應(yīng)utf-8格式的Base64編碼是"5LiK572R", 對應(yīng)GB2312格式的Base64編碼是"yc/N+A=="。
五、附錄C#版Base64的Unity的測試用例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Base64Test : MonoBehaviour
{
// Use this for initialization
void Start ()
? ? {
? ? ? ? string encodeStr = EncodeBase64String("Hello Base64");
? ? ? ? string decodeStr = DecodeBase64String(encodeStr);
? ? ? ? Debug.Log("EncodeBase64String: " + encodeStr);
? ? ? ? Debug.Log("DecodeBase64String: " + decodeStr);
}
? ? public string EncodeBase64String(string strValue_)
? ? {
? ? ? ? if(strValue_ != null && strValue_ != "")
? ? ? ? {
? ? ? ? ? ? byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strValue_);
? ? ? ? ? ? return System.Convert.ToBase64String(bytes);
? ? ? ? }
? ? ? ? return "";
? ? }
? ? public string DecodeBase64String(string strValue_)
? ? {
? ? ? ? if(strValue_ != null && strValue_ != "")
? ? ? ? {
? ? ? ? ? ? byte[] bytes = System.Convert.FromBase64String(strValue_);
? ? ? ? ? ? return System.Text.Encoding.UTF8.GetString(bytes);
? ? ? ? }
? ? ? ? return "";
? ? }
}