看图解http时看到首部字段Content-MD5,说先根据报文主体执行MD5编码,得到的二进制数在用Base64编码,最终得到一串字符,用于对报文主体的准确性校验。这MD5是什么?Base64又是什么?抱着这些疑问,花了半天整理了一下编码相关的基础知识,最后通过练习,最后初步了解为什么要编码,这些编码到底是怎么计算运行的。
ASCII
用8bit表示字符的编码格式,256个可用字符,128个已定义字符,其中33个控制字符(已陈废),95个可显字符。
ASCII码表
二进制
十进制
十六进制
图形
二进制
十进制
十六进制
图形
二进制
十进制
十六进制
图形
0010 0000
32
20
(space)
0100 0000
64
40
@
0110 0000
96
60
`
0010 0001
33
21
!
0100 0001
65
41
A
0110 0001
97
61
a
0010 0010
34
22
"
0100 0010
66
42
B
0110 0010
98
62
b
0010 0011
35
23
#
0100 0011
67
43
C
0110 0011
99
63
c
0010 0100
36
24
$
0100 0100
68
44
D
0110 0100
100
64
d
0010 0101
37
25
%
0100 0101
69
45
E
0110 0101
101
65
e
0010 0110
38
26
&
0100 0110
70
46
F
0110 0110
102
66
f
0010 0111
39
27
'
0100 0111
71
47
G
0110 0111
103
67
g
0010 1000
40
28
(
0100 1000
72
48
H
0110 1000
104
68
h
0010 1001
41
29
)
0100 1001
73
49
I
0110 1001
105
69
i
0010 1010
42
2A
*
0100 1010
74
4A
J
0110 1010
106
6A
j
0010 1011
43
2B
+
0100 1011
75
4B
K
0110 1011
107
6B
k
0010 1100
44
2C
,
0100 1100
76
4C
L
0110 1100
108
6C
l
0010 1101
45
2D
-
0100 1101
77
4D
M
0110 1101
109
6D
m
0010 1110
46
2E
.
0100 1110
78
4E
N
0110 1110
110
6E
n
0010 1111
47
2F
/
0100 1111
79
4F
O
0110 1111
111
6F
o
0011 0000
48
30
0
0101 0000
80
50
P
0111 0000
112
70
p
0011 0001
49
31
1
0101 0001
81
51
Q
0111 0001
113
71
q
0011 0010
50
32
2
0101 0010
82
52
R
0111 0010
114
72
r
0011 0011
51
33
3
0101 0011
83
53
S
0111 0011
115
73
s
0011 0100
52
34
4
0101 0100
84
54
T
0111 0100
116
74
t
0011 0101
53
35
5
0101 0101
85
55
U
0111 0101
117
75
u
0011 0110
54
36
6
0101 0110
86
56
V
0111 0110
118
76
v
0011 0111
55
37
7
0101 0111
87
57
W
0111 0111
119
77
w
0011 1000
56
38
8
0101 1000
88
58
X
0111 1000
120
78
x
0011 1001
57
39
9
0101 1001
89
59
Y
0111 1001
121
79
y
0011 1010
58
3A
:
0101 1010
90
5A
Z
0111 1010
122
7A
z
0011 1011
59
3B
;
0101 1011
91
5B
[
0111 1011
123
7B
{
0011 1100
60
3C
<
0101 1100
92
5C
\
0111 1100
124
7C
0011 1101
61
3D
=
0101 1101
93
5D
]
0111 1101
125
7D
}
0011 1110
62
3E
>
0101 1110
94
5E
^
0111 1110
126
7E
~
0011 1111
63
3F
?
0101 1111
95
5F
_
UNICODE
Unicode只是一个字符集,只规定了符号的二进制代码,但不规定这个二进制代码如何存储。实际字符与二进制代码转换时还需要用到具体转换格式,如UTF-8,UTF-16等。
BigEndian & LittleEndian
ANSI、UTF-16会区分big endian和little endian。
当用两个字节表示一个符号时,从第一个字节往后编码和解析的方式为Big Endian大头方式,从最后一个字节往前编码和解析的方式为LittleEndian小头方式。
Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。
如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式;如果头两个字节是FF FE,就表示该文件采用小头方式。
UTF-8
unicode的字符集庞大,一个字符长度可能是三个字节(24bit)甚至4个字节(32bit)。固定长度的编码方式容易造成资源极大浪费(UTF-16用两个或4个字节,UTF-32固定4个字节)。
基于unicode的一种变长的编码方式,可用1~4个字节表示单个符号。
UTF-8的编码规则:
对于单字节字符,字节第一位设为0,后面7位为这个符号的unicode码。因此对于英文字母和数字,UTF-8编码和ASCII编码是相同的。
对于n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0;后面字节的前两位设为10;剩下空余字节全部为这个符号的unicode码。
Unicode符号范围 | UTF-8编码方式
(十六进制)
(二进制)
0000 0000-0000 007F
0xxxxxxx
0000 0080-0000 07FF
110xxxxx 10xxxxxx
0000 0800-0000 FFFF
1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
UTF-8最大容量10FFFF,即1,114,111个字符。例子:
“严”对应unicode为4E25(100111000100101),判断占用三个字节,即格式为1110xxxx 10xxxxxx 10xxxxxx,然后从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出位数补0,即得到了“严”的UTF-8编码:11100100 10111000 10100101,转换成十六进制就是E4B8A5。
BASE64
Base64是基于64个可打印字符来表示二进制数据的表示方法。2的6次方为64,所以每6bits为一个单元,对应某个可打印字符。
64个字符包含a-zA-Z0-9功62个字符,以及加号“+”和斜杠“/”。等号“=”作为后缀补位符(不在64个字符之内)。
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文本后加上一个或两个等号“=”,代表补足的单位数。
MD5
Message-Digest Algorithm(消息摘要算法)简称MD5,一种被广泛使用的密码散列函数。输入不定长度信息,经过程序流程,生成四个32位数据,最后合在一起生成一个128位散列。
SHA
Secure Hash Algorithm(安全散列算法)缩写SHA,是一个密码散列函数家族。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。
最后回到Content-MD5
HTTP中Content-MD5即一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以确认消息传输到达。对报文主体执行MD5算法获得128位二进制数后,HTTP首部无法记录二进制值,所以还要通过Base64编码处理。例:
对”blog”做MD5编码结果:126AC9F6149081EB0E97C2E939EAAD52,再对MD5码的二进制做Base64编码:
MD5(三位)
二进制数
Base64对二进制数分割
Base64码
12 6A C9
0001 0010 0110 1010 1100 1001
000100 100110 101011 001001
EmrJ
F6 14 90
1111 0110 0001 0100 1001 0000
111101 100001 010010 010000
9hSQ
...
...
...
...
52
0101 0010
010100 100000
Ug==
最终Base64编码即 EmrJ9hSQgesOl8LpOeqtUg==
编码相关文章参考:http://www.ruanyifeng.com/blo...阮大师07年写了一篇通俗易懂的关于ASCII,unicode和utf-8的文章,至今都还有人在留言,拜服。