Base64 简要笔记及其他
Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。
1.base64 算法的由来
base64 最早是用作解决电子邮件的传输问题,由于历史原因,早期电子邮件只允许传输 ASCII 码字符,如果想传输一封带有非 ASCII 字符的邮件,在遇到一些老旧的网关就可能会对字符最高位进行调整,导致收到的邮件出现乱码。
2.base64 不是加密算法
base64 算法的编码和解码方法可以作为加密和解密操作,但是不能叫做加密算法,因为其算法和充当密钥的索引表都是公开的。最多是让在你身后的人一时看不懂,所谓防君子不防小人。
3.Base 编码方法
转换的时候,将三个 byte 的数据,先后放入一个 24bit 的缓冲区中,先来的 byte 占高位。数据不足 3byte 的话,剩下的 bit 用 0 补足。然后,每次取出 6 个 bit,按照其值选择索引表的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。
这里就不举例说明,具体可以参考维基百科。
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
/
5.一个简单的编码方法和译码方法实现:
HTML5 提供的通用 Base64 方法 API
1.编码: window.btoa(stringToEncode)
window.btoa(stringToEncode)只能将 ASCII 字符串或二进制数据转换成一个 base64 编码过的字符串,该方法不能直接作用于 Unicode 字符串。
2.解码: window.atob(encodedData)
window.atob(encodedData)将已经被 base64 编码过的数据进行解码。
3.作用于 UTF-8 编码的文字
但是这两个 Web API 功能很简单,并不能直接作用于 Unicode 字符串,所以当调用 btoa() 时若传入的不是 ASCII 或二进制字符串,比如汉字就会出错。
下面是别人提供的简单解决方法:
作者在这里使用了一个小小的Hack技巧。encodeURIComponent() 是ECMAscript中Global对象的URI方法,对URI进行编码,可以作用于所有Unicode字符。而 escape() 是已废弃的URI编码方法,功能和 encodeURIComponent() 相同,但是只能编码ASCII字符。
即 encodeURIComponent(str) 相当于 escape(unicodeToASCII(str)) ,则 unescape(encodeURIComponent(str)) 等同于 unicodeToASCII(str) ,所以就将 Unicode 字符转换成了 ASCII 字符。( unescape() 是和 escape() 对应的解码方法)
关于文字集和文字编码方面的知识,比如 UTF-8 是基于 Unicode 文字集的一种广泛使用的编码方式,具体此处不再赘述。
Data URL与Base64
这里主要说说 Data URL 模式和 Base64 ,比如下面这段代码:
这是一个真实的小例子,可以在百度网盘看到,会在控制台打印出百度云logo。这里用到了 console.log() 的一些稍微高级一点的用法,支持类似C语言 printf() 风格的打印方式,占位符 %c 可以使用一些CSS样式语句。比如这里使用的:
关于 console.log() 的用法以及 console 对象的其他方法、属性,具体此处不再赘述。
回到 url,可以看到一长串数据,在开头是这样的:
这就是 Data URL Scheme 的语法格式,后面是用 Base64 编码的图片数据。
完整的图片就像下面这样,可以直接复制到地址栏查看:
不过,Firefox 似乎不支持在控制台使用 Data URL,大概是由于这个原因,有时候可以降级在控制台直接使用一张图片。
参考资料:
Javascript高级程序设计(第3版)[人民邮电出版社]
Java加密与解密的艺术[机械工业出版社]
Last updated