看圖解http時看到首部字段Content-MD5,說先根據報文主體執行MD5編碼,獲得的二進制數在用Base64編碼,最終獲得一串字符,用於對報文主體的準確性校驗。這MD5是什麼?Base64又是什麼?抱着這些疑問,花了半天整理了一下編碼相關的基礎知識,最後經過練習,最後初步瞭解爲何要編碼,這些編碼究竟是怎麼計算運行的。html
用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只是一個字符集,只規定了符號的二進制代碼,但不規定這個二進制代碼如何存儲。實際字符與二進制代碼轉換時還須要用到具體轉換格式,如UTF-8,UTF-16等。函數
ANSI、UTF-16會區分big endian和little endian。編碼
當用兩個字節表示一個符號時,從第一個字節日後編碼和解析的方式爲Big Endian大頭方式,從最後一個字節往前編碼和解析的方式爲LittleEndian小頭方式。spa
Unicode規範中定義,每個文件的最前面分別加入一個表示編碼順序的字符,這個字符的名字叫作"零寬度非換行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。這正好是兩個字節,並且FF比FE大1。
若是一個文本文件的頭兩個字節是FE FF,就表示該文件採用大頭方式;若是頭兩個字節是FF FE,就表示該文件採用小頭方式。code
unicode的字符集龐大,一個字符長度多是三個字節(24bit)甚至4個字節(32bit)。固定長度的編碼方式容易形成資源極大浪費(UTF-16用兩個或4個字節,UTF-32固定4個字節)。htm
基於unicode的一種變長的編碼方式,可用1~4個字節表示單個符號。blog
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是基於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文本後加上一個或兩個等號「=」,表明補足的單位數。
Message-Digest Algorithm(消息摘要算法)簡稱MD5,一種被普遍使用的密碼散列函數。輸入不定長度信息,通過程序流程,生成四個32位數據,最後合在一塊兒生成一個128位散列。
Secure Hash Algorithm(安全散列算法)縮寫SHA,是一個密碼散列函數家族。能計算出一個數字消息所對應到的,長度固定的字符串(又稱消息摘要)的算法。
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的文章,至今都還有人在留言,拜服。