Base64除了可以做簡單的加密之外,通過整個介紹我沒能看出有什麼其他應用場景。
Base64是網絡上最常見的用於傳輸8Bit字節代碼的編碼方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的詳細規範。Base64編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統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要求把每三個8Bit的
字節轉換爲四個6Bit的字節(3*8 = 4*6 = 24),然後把6Bit再添兩位高位0,組成四個8Bit的字節,也就是說,轉換後的字符串理論上將要比原來的長1/3。
規則
關於這個編碼的規則:
③.最後的結束符也要處理..
這樣說會不會太抽象了?不怕,我們來看一個例子:
轉換前 aaaaaabb ccccdddd eeffffff
轉換後 00aaaaaa 00bbcccc 00ddddee 00ffffff
應該很清楚了吧?上面的三個
字節是原文,下面的四個字節是轉換後的Base64編碼,其前兩位均爲0。
轉換後,我們用一個碼錶來得到我們想要的字符串(也就是最終的Base64編碼),這個表是這樣的:(摘自RFC2045)
轉換表
Table 1: The Base64 Alphabet
索引
|
對應字符
|
索引
|
對應字符
|
索引
|
對應字符
|
索引
|
對應字符
|
0
|
A
|
17
|
R
|
34
|
i
|
51
|
z
|
1
|
B
|
18
|
S
|
35
|
j
|
52
|
0
|
2
|
C
|
19
|
T
|
36
|
k
|
53
|
1
|
3
|
D
|
20
|
U
|
37
|
l
|
54
|
2
|
4
|
E
|
21
|
V
|
38
|
m
|
55
|
3
|
5
|
F
|
22
|
W
|
39
|
n
|
56
|
4
|
6
|
G
|
23
|
X
|
40
|
o
|
57
|
5
|
7
|
H
|
24
|
Y
|
41
|
p
|
58
|
6
|
8
|
I
|
25
|
Z
|
42
|
q
|
59
|
7
|
9
|
J
|
26
|
a
|
43
|
r
|
60
|
8
|
10
|
K
|
27
|
b
|
44
|
s
|
61
|
9
|
11
|
L
|
28
|
c
|
45
|
t
|
62
|
+
|
12
|
M
|
29
|
d
|
46
|
u
|
63
|
/
|
13
|
N
|
30
|
e
|
47
|
v
|
|
|
14
|
O
|
31
|
f
|
48
|
w
|
|
|
15
|
P
|
32
|
g
|
49
|
x
|
|
|
16
|
Q
|
33
|
h
|
50
|
y
|
|
|
舉例
讓我們再來看一個實際的例子,加深印象!
轉換前 10101101 1011 1010 0111 0110
轉換後 00101011 00011011 00101001 00110110
十進制 43 27 41 54
對應碼錶中的值 r b p 2
所以上面的24位編碼,編碼後的Base64值爲 rbp2
解碼同理,把 rbq2 的二進制位連接上再重組得到三個8位值,得出原碼。
(解碼只是編碼的逆過程,在此我就不多說了,另外有關MIME的RFC還是有很多的,如果需要詳細情況請自行查找。)
第一個字節,根據源字節的第一個字節處理。
規則:源第一字節右移兩位,去掉低2位,高2位補零。
既:00 + 高6位
第二個字節,根據源字節的第一個字節和第二個字節聯合處理。
規則如下,第一個字節高6位去掉左移四位,第二個字節右移四位
即:源第一字節低2位 + 源第2字節高4位
第三個字節,根據源字節的第二個字節和第三個字節聯合處理,
規則第二個字節去掉高4位並左移兩位(得高6位),第三個字節右移6位並去掉高6位(得低2位),相加即可
第四個字節,規則,源第三字節去掉高2位即可
根據base64的編碼規則,每76個字符需要一個換行
// 用更接近於
編程的思維來說,編碼的過程是這樣的:
//第一個
字符通過右移2位獲得第一個目標字符的Base64表位置,根據這個數值取到表上相應的字符,就是第一//個目標字符。
// 然後將第一個
字符左移4位加上第二個字符右移4位,即獲得第二個目標字符。
//再將第二個
字符左移2位加上第三個字符右移6位,獲得第三個目標字符。
//最後取第三個
字符的右6位即獲得第四個目標字符。
//在以上的每一個步驟之後,再把結果與 0x3F 進行 AND
位操作,就可以得到編碼後的
字符了。
可是等等……聰明的你可能會問到,原文的
字節數量應該是3的倍數啊,如果這個條件不能滿足的話,那該怎麼辦呢?
我們的解決辦法是這樣的:原文的
字節不夠的地方可以用全0來補足,轉換時Base64編碼用=號來代替。這就是爲什麼有些Base64編碼會以一個或兩個等號結束的原因,但等號最多隻有兩個。因爲:
餘數 = 原文字節數 MOD 3
所以餘數任何情況下都只可能是0,1,2這三個數中的一個。如果餘數是0的話,就表示原文字節數正好是3的倍數(最理想的情況啦)。如果是1的話,爲了讓Base64編碼是3的倍數,就要補2個等號;同理,如果是2的話,就要補1個等號。
應用
Base64編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統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)。
其他應用
Mozilla Thunderbird和Evolution用Base64來保密
電子郵件密碼
Base64 也會經常用作一個簡單的“加密”來保護某些數據,而真正的加密通常都比較繁瑣。
垃圾訊息傳播者用Base64來避過反垃圾郵件工具,因爲那些工具通常都不會翻譯Base64的訊息。
在LDIF檔案,Base64用作編碼字串。
原理
先以“
迅雷下載”爲例: 很多下載類網站都提供“迅雷下載”的鏈接,其地址通常是加密的迅雷專用下載地址。
如thunder://QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
其實
迅雷的“專用地址”也是用Base64加密的,其加密過程如下:
一、在地址的前後分別添加AA和ZZ
如http://www.baidu.com/img/sslm1_logo.gif變成
AAhttp://www.baidu.com/img/sslm1_logo.gifZZ
二、對新的字符串進行Base64編碼
如AAhttp://www.baidu.com/img/sslm1_logo.gifZZ用Base64編碼得到
QUFodHRwOi8vd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWZaWg==
另: Flashget的與
迅雷類似,只不過在第一步時加的“料”不同罷了,Flashget在地址前後加的“料”是[FLASHGET]
而QQ旋風的乾脆不加料,直接就對地址進行Base64編碼了