加密標準的JavaScript庫https://github.com/brix/crypto-js
簡介
標準的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。
規則
關於這個編碼的規則:
①.把3個字節變成4個字節。
②每76個字符加一個換行符。
③.最後的結束符也要處理。
例子1
轉換前 11111111, 11111111, 11111111 (二進制)
轉換後 00111111, 00111111, 00111111, 00111111 (二進制)
上面的三個字節是原文,下面的四個字節是轉換後的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 |
例子2
轉換前 10101101,10111010,01110110
轉換後 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位即可
//用更接近於編程的思維來說,編碼的過程是這樣的:
//第一個字符通過右移2位獲得第一個目標字符的Base64表位置,根據這個數值取到表上相應的字符,就是第一//個目標字符。
//然後將第一個字符與0x03(00000011)進行與(&)操作並左移4位,接着第二個字符右移4位與前者相或(|),即獲得第二個目標字符。
//再將第二個字符與0x0f(00001111)進行與(&)操作並左移2位,接着第三個字符右移6位與前者相或(|),獲得第三個目標字符。
//最後將第三個字符與0x3f(00111111)進行與(&)操作即獲得第四個目標字符。
//在以上的每一個步驟之後,再把結果與 0x3F 進行 AND 位操作,就可以得到編碼後的字符了。
原文的字節數量應該是3的倍數,如果這個條件不能滿足的話,具體的解決辦法是這樣的:原文剩餘的字節根據編碼規則繼續單獨轉(1變2,2變3;不夠的位數用0補全),再用=號補滿4個字節。這就是爲什麼有些Base64編碼會以一個或兩個等號結束的原因,但等號最多隻有兩個。因爲一個原字節至少會變成兩個目標字節,所以餘數任何情況下都只可能是0,1,2這三個數中的一個。如果餘數是0的話,就表示原文字節數正好是3的倍數(最理想的情況)。如果是1的話,轉成2個Base64編碼字符,爲了讓Base64編碼是4的倍數,就要補2個等號;同理,如果是2的話,就要補1個等號。
原理
轉碼過程例子:
3*8=4*6
內存1個字節佔8位
轉前: s 1 3
先轉成ascii:對應 115 49 51
2進制: 01110011 00110001 00110011
6個一組(4組) 011100110011000100110011
然後纔有後面的 011100 110011 000100 110011
然後計算機一個字節佔8位,不夠就自動補兩個高位0了
所以有了高位補0
科學計算器輸入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查對下照表 c z E z
先以“迅雷下載”爲例: 很多下載類網站都提供“迅雷下載”的鏈接,其地址通常是加密的迅雷專用下載地址。
其實迅雷的“專用地址”也是用Base64"加密"的,其過程如下:
一、在地址的前後分別添加AA和ZZ
二、對新的字符串進行Base64編碼
應用
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用作編碼字串。
代碼實現
JavaScript版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
|
在MIME格式的電子郵件中,base64可以用來將binary的字節序列數據編碼成ASCII字符序列構成的文本。使用時,在傳輸編碼方式中指定base64。使用的字符包括大小寫字母各26個,加上10個數字,和加號“+”,斜槓“/”,一共64個字符,等號“=”用來作爲後綴用途。
完整的base64定義可見 RFC1421和 RFC2045。編碼後的數據比原始數據略長,爲原來的4/3。在電子郵件中,根據RFC822規定,每76個字符,還需要加上一個回車換行。可以估算編碼後數據長度大約爲原長的135.1%。
轉換的時候,將三個byte的數據,先後放入一個24bit的緩衝區中,先來的byte佔高位。數據不足3byte的話,於緩衝區中剩下的Bit用0補足。然後,每次取出6個bit,按照其值選擇ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作爲編碼後的輸出。不斷進行,直到全部輸入數據轉換完成。
如果最後剩下兩個輸入數據,在編碼結果後加1個“=”;如果最後剩下一個輸入數據,編碼結果後加2個“=”;如果沒有剩下任何數據,就什麼都不要加,這樣纔可以保證資料還原的正確性。
舉例來說,一段引用自Thomas Hobbes's Leviathan的文句:
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=