在数据传输的时候,并不是所有的字符都可以受到支持,很多时候只能传输可见字符,对于不可见字符的传输需要经过特殊处理,这就是 Base64 产生的原因。Base64 编码是一种基于 64 个可打印字符来表示二进制数据的表示方法。由于 ,所以每 6 个比特为一个单元,对应某个可打印字符。3 个字节有 24 个比特,对应于 4 个 Base64 单元,即 3 个字节可由 4 个可打印字符来表示。在 Base64 中的可打印字符包括字母 A-Z、a-z、数字 0-9,这样共有 62 个字符,此外两个可打印符号在不同的系统中而不同。一些如 uuencode 的其他编码方法,和之后 BinHex 的版本使用不同的 64 字符集来代表 6 个二进制数字,但是不被称为 Base64。 Base64 常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据,包括 MIME 的电子邮件及 XML 的一些复杂数据。用 Base64 编码图片也是互联网上常见的做法。
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 值,最后附加一个等号。可以参考下面的例子:
这是一个用 Python 实现 Base64 编码的脚本:
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 def myBase64Encode (preCoding ): charTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' if len(preCoding) < 0 : return '' lackCharNums = 3 - len(preCoding) % 3 if lackCharNums == 3 : lackCharNums = 0 for i in range(lackCharNums) : preCoding = preCoding + b'\x00' result = '' rp = '' for i in range(int(len(preCoding) / 3 )): threeChar = preCoding[i * 3 : i * 3 + 3 ] tCode = '' pCode = '' for j in range(3 ) : pCode = bin(threeChar[j])[2 :] lackZeroNums = 8 - len(pCode) for x in range(lackZeroNums): pCode = '0' + pCode tCode = tCode + pCode pCode = '' for j in range(4 ): pCode = tCode[j * 6 : j * 6 + 6 ] rp = rp + charTable[int(pCode, 2 )] result = rp[: len(rp) - lackCharNums] for j in range(lackCharNums): result = result + '=' return bytes(result, encoding = "utf-8" ) def myBase64Decode (encodedBin ) : charTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' if not len(encodedBin) % 4 == 0 : return '' tCode = '' pCpde = '' for i in encodedBin: for j in range(len(charTable)): if chr(i) == charTable[j]: pCode = bin(j)[2 :] lackZeroNums = 6 - len(pCode) for x in range(lackZeroNums): pCode = '0' + pCode tCode = tCode + pCode pCode = '' result = '' for i in range(int(len(tCode) / 8 )): pCode = tCode[i * 8 : i * 8 + 8 ] result = result + chr(int(pCode, 2 )) return bytes(result, encoding = "utf-8" ) print(myBase64Encode(b"helloworld" )) print(myBase64Decode(b"aGVsbG93b3JsZA==" ))
浏览器中可以直接调用相关的 API:
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 <!DOCTYPE html > <html > <head > <meta charset ="UTF-8" /> <title > 文件base64——直接拖进来</title > </head > <style > body { word-break: break-all; } </style > <body > <script > window .addEventListener("dragenter" , function (event ) { event.preventDefault(); }, false ); window .addEventListener("dragover" , function (event ) { event.preventDefault(); }, false ); window .addEventListener("drop" , function (event ) { const reader = new FileReader(); reader.onload = function (e ) { document .body.insertAdjacentHTML("afterBegin" , "<p>" + e.target.result + "</p>" ); }; reader.readAsDataURL(event.dataTransfer.files[0]); event.preventDefault(); }, false ); </script > </body > </html >
这是加载 Base64 编码的图片的方法。这可以将图片硬编码到网页中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <!DOCTYPE html > <html > <head > <meta charset ="UTF-8" /> <title > Base64 Encode编码实现1x1px透明(黑白)图片</title > <style > body { text-align: center; } </style > </head > <body > <h1 > 以下是透明图片</h1 > <img src ="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width ="500" height ="100" /> <h1 > 以下是黑色图片</h1 > <img src ="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=" width ="500" height ="100" /> </body > </html >
拓展阅读:Base64 - 维基百科 Base64 编码原理及脚本的简单实现