字符集只是一個規則集合的名字,對應到真實生活中,字符集就是對某種語言的稱呼。例如:英語,漢語,日語。
對于一個字符集來說要正確編碼轉碼一個字符需要三個關鍵元素:
1)字庫表(character repertoire):是一個相當于所有可讀或者可顯示字符的數據庫,字庫表決定了整個字符集能夠展現表示的所有字符的范圍;
2)編碼字符集(coded character set):即用一個編碼值code point來表示一個字符在字庫中的位置;
3)字符編碼(character encoding form):將編碼字符集和實際存儲數值之間的轉換關系。
一般來說都會直接將code point的值作為編碼后的值直接存儲。例如在ASCII中“A”在表中排第65位,而編碼后A的數值是 0100 0001 也即十進制的65的二進制轉換結果。
看到這里,可能很多讀者都會有和我當初一樣的疑問:字庫表和編碼字符集看來是必不可少的,那既然字庫表中的每一個字符都有一個自己的序號,直接把序號作為存儲內容就好了。為什么還要多此一舉通過字符編碼把序號轉換成另外一種存儲格式呢?
其實原因也比較容易理解:統一字庫表的目的是為了能夠涵蓋世界上所有的字符,但實際使用過程中會發現真正用的上的字符相對整個字庫表來說比例非常低。例如中文地區的程序幾乎不會需要日語字符,而一些英語國家甚至簡單的ASCII字庫表就能滿足基本需求。而如果把每個字符都用字庫表中的序號來存儲的話,每個字符就需要3個字節(這里以Unicode字庫為例),這樣對于原本用僅占一個字符的ASCII編碼的英語地區國家顯然是一個額外成本(存儲體積是原來的三倍)。算的直接一些,同樣一塊硬盤,用ASCII可以存1500篇文章,而用3字節Unicode序號存儲只能存500篇。于是就出現了UTF-8這樣的變長編碼。在UTF-8編碼中原本只需要一個字節的ASCII字符,仍然只占一個字節。而像中文及日語這樣的復雜字符就需要2個到3個字節來存儲。
關于字符編碼知識的詳細講解請見:《字符編碼那點事:快速理解ASCII、Unicode、GBK和UTF-8》。