本文來自該鏈接的總結,截圖來自該鏈接,后續會繼續看該鏈接並更新隨筆:
https://kunststube.net/encoding/
首先讓我們來看看什么是編碼和解碼:
來一個小例子:
apple -> 蘋果。
為什么在我們腦海中apple對應蘋果呢?我們可以認為在腦海中有一張表,表里面“apple”這個東西指向了“蘋果”。
其實編碼就是通過一個對應表,把01位串映射到我們人類可以讀懂的字符。
以上是ASCII編碼的部分編碼規則,ASCII編碼把一連串的01位串每八個做一次映射。解碼請自行理解。
接着讓我們來看看Unicode編碼是什么:
我們知道,這個世界上有很多種編碼,big5,gb18030,Shift-JIS,Mac Roman,utf-8等,其中utf-8能夠編碼絕大多數字符,如果其不能編碼,意味着文件中有的01位串是錯誤的,我們也知道,一個字節(8bit)可以編碼256種符號,那么一個漢字能否用一個字節來編碼呢?顯然不夠,因為漢字不止256個。那么兩個字節呢,欸,可以,big5就是這樣的一個編碼方式(01位串與字符的對照表),它使用兩個字節來編碼漢字,而且big5涵蓋了大多數的繁體字,簡體字應該沒有很好支持。gb18030則同時涵蓋了簡體和繁體字(簡體和繁體字在gb18030這張表上有表項)。
下圖是gb18030編碼表的一部分,可見其在解碼01位串的時候會每16位進行截斷,然后做映射。
不同編碼編碼的字符范圍不同,那么如何對這些編碼做一個統一呢,Unicode可以做到。
Unicode基本上記錄了所有的字符它一共可以定義上千萬種符號,那么Unicode需要采用的編碼單位是多少位呢?答案是0,因為Unicode沒有被用來當作編碼方式,它只是記錄了所有字符與數字的對應關系,它不是編碼表。
其次再討論一下不同的編碼方式對二進制串的解釋:
個人認為,不同的編碼方式是為了編碼不同的語言誕生的,所以對0000 0001的解碼對應的字符也很容易有所不同,因為每種語言種人們覺得最基本的符號不同(漢字可以是‘一’英文可以是‘a’日文中也許是‘
の’),所以同一個位串,在不同的編碼方式種,很容易對應不同的字符。
同樣的,同一個字符在不同的編碼方式中會被編碼成不同的01位串:
最后討論一下為什么把用編碼方式A編碼的文件用另一種編碼方式B保存之后,該文件便基本被破壞而且很難還原:
當我們用A(比如gbk)解碼該文件后,再把他保存為令一種編碼方式的文件,也就是用另一個編碼表B(比如utf8)去把字符編碼為01位串(這樣保存實際上再保存亂碼),通過上面的一張圖片我們可以知道,同樣的字符再不同的編碼方式種會被編碼為不同的01位串,也就是說該文件的01數據會被改變!一旦保存,那么我們用原來的編碼表A去解碼的時候仍然會亂碼,因為該文件內的01bit已經被改變,除非你用B去解碼保存后的文件,當然看到的會是亂碼,然后再用A去編碼,再保存,那么文件就會還原了。能還原的前提是你知道你用什么編碼改變了該文件,而且原來的編碼方式是什么。(試想一下,你從網上下載了一個文件,打開之后發現是亂碼,你能怎么辦?)