Day13_01_Java中的加解密之Base64编码
01_Java中的加解密之Base64編碼
一.Base64編碼:
一. 概念:
Base64是網絡上最常見的用于傳輸8Bit字節代碼的編碼方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的詳細規范。Base64編碼可用于在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就采用了Base64來將一個較長的唯一標識符(一般為128-bit的UUID)編碼為一個字符串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,采用Base64編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
Base64編碼算法原理:
Base64編碼要求把3個8位字節(3x8=24)轉化為4個6位的字節(4x6=24),之后在6位的前面補兩個0,形成8位一個字節的形式。 如果剩下的字符不足3個字節,則用0填充,輸出字符使用'=',因此編碼后輸出的文本末尾可能會出現1或2個'='。
為了保證所輸出的編碼位可讀字符,Base64制定了一個編碼表,以便進行統一轉換。編碼表的大小為26=64,這也是Base64名稱的由來。編碼表見附錄!
二. 實現原理:
轉碼過程例子:原始信息111.利用Base64來進行編碼,看最終結果是什么?
3x8=4x6
內存中1個字符占8位.
轉換前: 1 1 1
1??.先轉成ASCII碼表對應的值:
ASCII碼表值對應: 49 49 49
2??.轉換成對應的2進制:
00110001 00110001 00110001
3??.6個一組進行重新劃分為4組:
001100 010011 000100 110001
4??.然后計算機是8位8位的存數 6不夠,自動就補兩個高位0了.
所以有了高位補0.
科學計算器輸入 00001100 00010011 00000100 00110001
得到 12 19 4 49
5??.查對下Base64對照表,得到最終結果: M T E x
先以“迅雷下載”為例: 很多下載類網站都提供“迅雷下載”的鏈接,其地址通常是加密的迅雷專用下載地址。
其實迅雷的“專用地址”也是用Base64"加密"的,其過程如下:
1.在地址的前后分別添加AA和ZZ;
2.對新的字符串進行Base64編碼.
另:Flashget的與迅雷類似,只不過在第一步時加的“料”不同罷了,Flashget在地址前后加的“料”是[FLASHGET],而QQ旋風的干脆不加料,直接就對地址進行Base64編碼了.
三. 詳細規則:
標準的Base64并不適合直接放在URL里傳輸,因為URL編碼器會把標準Base64中的“/”和“+”字符變為形如“%XX”的形式,而這些“%”號在存入數據庫時還需要再進行轉換,因為ANSI SQL中已將“%”號用作通配符。為解決此問題,可采用一種用于URL的改進Base64編碼,它在末尾填充'='號,并將標準Base64中的“+”和“/”分別改成了“-”和“_”,這樣就免去了在URL編解碼和數據庫存儲時所要作的轉換,避免了編碼信息長度在此過程中的增加,并統一了數據庫、表單等處對象標識符的格式。
另有一種用于正則表達式的改進Base64變種,它將“+”和“/”改成了“!”和“-”,因為“+”,“*”以及前面在IRCu中用到的“[”和“]”在正則表達式中都可能具有特殊含義。
此外還有一些變種,它們將“+/”改為“_-”或“._”(用作編程語言中的標識符名稱)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。Base64要求把每三個8Bit的字節轉換為四個6Bit的字節(3x8 = 4x6 = 24),然后把6Bit再添兩位高位0,組成四個8Bit的字節,也就是說,轉換后的字符串理論上將要比原來的長1/3。
規則:關于這個編碼的規則:
①.把3個字符變成4個字符。
②每76個字符加一個換行符。
③.最后的結束符也要處理。
例子(1)
轉換前 11111111, 11111111, 11111111 (二進制)
轉換后 00111111, 00111111, 00111111, 00111111 (二進制)
上面的三個字節是原文,下面的四個字節是轉換后的Base64編碼,其前兩位均為0。
轉換后,我們用一個碼表來得到我們想要的字符串(也就是最終的Base64編碼),這個表是這樣的:(摘自RFC2045)
四. Java中編碼解碼過程:
// 加密傳入的數據是byte類型的,并非使用decode方法將原始數據轉二進制,String類型的數據 使用 str.getBytes()即可 String str = "Hello!"; // 在這里使用的是encode方式,返回的是byte類型加密數據,可使用new String轉為String類型 String strBase64 = new String(Base64.encode(str.getBytes(), Base64.DEFAULT)); Log.i("Test", "encode >>>" + strBase64); // 這里 encodeToString 則直接將返回String類型的加密數據 String enToStr = Base64.encodeToString(str.getBytes(), Base64.DEFAULT); Log.i("Test", "encodeToString >>> " + enToStr); // 對base64加密后的數據進行解密 Log.i("Test", "decode >>>" + new String(Base64.decode(strBase64.getBytes(), Base64.DEFAULT)));CRLF: 這個參數看起來比較眼熟,它就是Win風格的換行符,意思就是使用CR LF這一對作為一行的結尾而不是Unix風格的LF.
DEFAULT: 這個參數是默認,使用默認的方法來編碼.
NO_PADDING: 這個參數是略去加密字符串最后的”=”.
NO_WRAP: 這個參數意思是略去所有的換行符(設置后CRLF就沒用了).
URL_SAFE: 這個參數意思是加密時不使用對URL和文件名有特殊意義的字符來作為加密字符,具體就是以-和_取代+和/.
五. 附錄:Base64編碼對照表:

六. ASCII碼表:




總結
以上是生活随笔為你收集整理的Day13_01_Java中的加解密之Base64编码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux服务器系统时间和bios时间,
- 下一篇: ql的python学习之路-day7