Base64編碼


Base64
是一種基於64個可打印字符來表示二進制數據的表示方法。因爲{\displaystyle 2^{6}=64}{\displaystyle 2^{6}=64},因此每6個比特爲一個單元,對應某個可打印字符。3個字節有24個比特,對應於4個Base64單元,即3個字節可由4個可打印字符來表示。它可用來做爲電子郵件的傳輸編碼。在Base64中的可打印字符包括字母A-Za-z數字0-9,這樣共有62個字符,此外兩個可打印符號在不一樣的系統中而不一樣。一些如uuencode的其餘編碼方法,和以後BinHex的版本使用不一樣的64字符集來表明6個二進制數字,可是不被稱爲Base64。


Base64經常使用於在一般處理文本數據的場合,表示、傳輸、存儲一些二進制數據,包括MIME電子郵件XML的一些複雜數據。php

MIME

MIME格式的電子郵件中,Base64能夠用來將binary的字節序列數據編碼ASCII字符序列構成的文本。使用時,在傳輸編碼方式中指定Base64。使用的字符包括大小寫拉丁字母各26個、數字10個、加號+和斜槓/,共64個字符,等號=用來做爲後綴用途。html

完整的Base64定義可見RFC 1421和RFC 2045。編碼後的數據比原始數據略長,爲原來的{\displaystyle {\frac {4}{3}}}{\frac {4}{3}}。在電子郵件中,根據RFC 822規定,每76個字符,還須要加上一個回車換行。能夠估算編碼後數據長度大約爲原長的135.1%。正則表達式

轉換的時候,將3字節的數據,前後放入一個24位的緩衝區中,先來的字節佔高位。數據不足3字節的話,於緩衝器中剩下的比特用0補足。每次取出6比特(由於{\displaystyle 2^{6}=64}{\displaystyle 2^{6}=64}),按照其值選擇ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符做爲編碼後的輸出,直到所有輸入數據轉換完成。算法

若原數據長度不是3的倍數時且剩下1個輸入數據,則在編碼結果後加2個=;若剩下2個輸入數據,則在編碼結果後加1個=數據庫

例子

舉例來講,一段引用自托馬斯·霍布斯利維坦》的文句:編程

Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.

通過Base64編碼以後變成:服務器

TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
  • 編碼「Man」
文本 M a n
ASCII編碼 77 97 110
二進制位 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0
索引 19 22 5 46
Base64編碼 T W F u

在此例中,Base64算法將3個字節編碼爲4個字符。編程語言

Base64索引表:函數

數值 字符   數值 字符   數值 字符   數值 字符
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 /

若是要編碼的字節數不能被3整除,最後會多出1個或2個字節,那麼能夠使用下面的方法進行處理:先使用0字節值在末尾補足,使其可以被3整除,而後再進行Base64的編碼。在編碼後的Base64文本後加上一個或兩個=號,表明補足的字節數。也就是說,當最後剩餘兩個八位字節(2個byte)時,最後一個6位的Base64字節塊有四位是0值,最後附加上兩個等號;若是最後剩餘一個八位字節(1個byte)時,最後一個6位的base字節塊有兩位是0值,最後附加一個等號。 參考下表:工具

文本(1 Byte) A    
二進制位 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
二進制位(補0) 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Base64編碼 Q Q = =
文本(2 Byte) B C  
二進制位 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
二進制位(補0) 0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0
Base64編碼 Q k M =

UTF-7

UTF-7是一個修改版Base64(Modified Base64)。主要是將UTF-16的數據,用Base64的方法編碼爲可打印的ASCII字符序列。目的是傳輸Unicode數據。主要的區別在於不用等號=補餘,由於該字符一般須要大量的轉譯。

標準可見 RFC 2152,《A Mail-Safe Transformation Format of Unicode》。

IRCu

IRCu等軟件所使用的P10 IRC服務器間協議中,對客戶與服務器的消息類型號(client/server numerics)和二進制IP地址採用了Base64編碼。消息類型號的長度固定爲3字節,故可直接編碼爲4個字節而不須要加填充。對IP地址進行編碼時,則須要在地址前添加一些0比特,使之能夠編碼爲整數個字節。這裏所用的符號集與前述MIME的也有所不一樣,將+/改爲了[]

在URL中的應用

Base64編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java持久化系統Hibernate中,就採用了Base64來將一個較長的惟一標識符(通常爲128-bit的UUID)編碼爲一個字符串,用做HTTP表單和HTTP GET URL中的參數。在其餘應用程序中,也經常須要把二進制數據編碼爲適合放在URL(包括隱藏表單域)中的形式。此時,採用Base64編碼不只比較簡短,同時也具備不可讀性,即所編碼的數據不會被人用肉眼所直接看到。

然而,標準的Base64並不適合直接放在URL裏傳輸,由於URL編碼器會把標準Base64中的/+字符變爲形如%XX的形式,而這些%號在存入數據庫時還須要再進行轉換,由於ANSI SQL中已將%號用做通配符。

爲解決此問題,可採用一種用於URL的改進Base64編碼,它不在末尾填充=號,並將標準Base64中的+/分別改爲了-_,這樣就免去了在URL編解碼和數據庫存儲時所要做的轉換,避免了編碼信息長度在此過程當中的增長,並統一了數據庫、表單等處對象標識符的格式。

另有一種用於正則表達式的改進Base64變種,它將+/改爲了!-,由於+*以及前面在IRCu中用到的[]正則表達式中均可能具備特殊含義。

此外還有一些變種,它們將+/改成_-._(用做編程語言中的標識符名稱)或.-(用於XML中的Nmtoken)甚至_:(用於XML中的Name)。

其餘應用

  • 垃圾消息傳播者用Base64來避過反垃圾郵件工具,由於那些工具一般都不會翻譯Base64的消息。
  • LDIF文件,Base64用做編碼字符串。

相關事件

  • 2018年2月電子郵件程序 Exim 發現重大漏洞,編號爲 CVE-2018-6789 的緩衝溢出漏洞容許攻擊者在服務器上遠程執行惡意代碼。漏洞位於 base64 解碼函數中,影響 Exim v4.90.1 以前的全部版本,多達 40 萬服務器受到影響。
相關文章
相關標籤/搜索