由 Content-MD5 报文头引出关于编码的学习

看图解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的编码规则:

  1. 对于单字节字符,字节第一位设为0,后面7位为这个符号的unicode码。因此对于英文字母和数字,UTF-8编码和ASCII编码是相同的。

  2. 对于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的文章,至今都还有人在留言,拜服。

你可能感兴趣的:(ascii,unicode,utf-8,base64)