字符集與編碼

2022-03-09 21:48:26 字數 3092 閱讀 4791

這些東西是自己在知乎上看的,摘抄下來,以便以後查閱,主要內容有:字符集與編碼、byte order mark等。

在windows中經常需要用到多字元與寬字元的轉換方法,多字元(multichar)也就是ansi編碼的方式,而寬字元(widechar)也就是unicode編碼的方式。

ansi是預設的編碼方式。對於英文檔案是ascii編碼,對於簡體中文檔案是gb2312編碼(只針對windows簡體中文版,如果是正體中文版會採用big5碼)。

回答的作者是梁海

簡答。一些細節暫無精力查證,如果說錯了還請指出。

一句話建議:涉及相容性考量時,不要用記事本,用專業的文字編輯器儲存為不帶 bom 的 utf-8。

* * *

如果是為了跨平台相容性,只需要知道,在 windows 記事本的語境中:

gbk 等遺留編碼最麻煩,所以除非你知道自己在幹什麼否則不要再用了。

utf-16 理論上其實很好,位元組序也標明了,但 utf-16 畢竟不常用。

utf-8 本來是相容性最好的編碼但 windows 偏要加 bom 於是經常出問題。

所以,跨平台相容性最好的其實就是不用記事本。

建議用 notepad++ 等正常的專業文字編輯器儲存為不帶 bom 的 utf-8。

另外,如果文字中所有字元都在 ascii 範圍內,那麼其實,記事本儲存的所謂的「ansi」檔案,和 ascii 或無 bom 的 utf-8 是一樣的。

* * *

阮一峰那篇〈字元編碼筆記:ascii,unicode和utf-8〉的確很有名,但從那篇文章能看出來他其實還是沒完全搞清楚 unicode 和 utf-8 的關係。他依舊被 windows 的混亂措詞誤導。事實上,幾年前我讀完他那篇文章之後依舊一頭霧水,最終還是自己看維基百科看明白的。

* * *

關於字符集(character set)和編碼(encoding),某幾篇答案中似乎有些混淆。

對於 ascii、gb 2312、big5、gbk、gb 18030 之類的遺留方案來說,基本上乙個字符集方案只使用一種編碼方案。

比如 ascii 這部標準本身就直接規定了字元和字元編碼的方式,所以既是字符集又是編碼方案;而 gb 2312 只是乙個區位碼形式的字符集標準,不過實際上基本都用 euc-cn 來編碼,所以提及「gb 2312」時也說的是乙個字符集和編碼連鎖的方案;gbk 和 gb 18030 等向後相容於 gb 2312 的方案也類似。

於是,很多人受這些遺留方案的影響而無法理解字符集和編碼的關係。

對於 unicode,字符集和編碼是明確區分的。unicode/ucs 標準首先是個統一的字符集標準。而 unicode/ucs 標準同時也定義了幾種可選的編碼方案,在標準文件中稱作「encoding form」,主要包括 utf-8、utf-16 和 utf-32。

所以,對 unicode 方案來說,同樣的基於 unicode 字符集的文字可以用多種編碼來儲存、傳輸。

所以,用「unicode」來稱呼乙個編碼方案不合適,並且誤導。

* * *

[1] windows 裡說的「ansi」其實是 windows code pages,這個模式根據當前 locale 選定具體的編碼,比如簡中 locale 下是 gbk。把自己這些 code page 稱作「ansi」是 windows 的

臭毛病。在 ascii 範圍內它們應該是和 ascii 一致的。

[2] 把帶有 bom 的小端序 utf-16 稱作「unicode」也是 windows 的

臭毛病。windows 從 windows 2000 開始就已經支援 surrogate pair 了,所以已經是 utf-16 了,「ucs-2」這個說法已經不合適了。ucs-2 只能編碼 bmp 範圍內的字元,從 1996 年起就在 unicode/iso 標準中被 utf-16 取代了(utf-16 通過蛋疼的 surrogate pair 來編碼超出 bmp 的字元)。都十多年了,求求大家別再誤稱了……

[3] 把帶 bom 的 utf-8 稱作「utf-8」又是 windows 的

臭毛病。如果忽略 bom,那麼在 ascii 範圍內與 ascii 一致。

* * *

utf-8 不需要 bom,儘管 unicode 標準允許在 utf-8 中使用 bom。

所以不含 bom 的 utf-8 才是標準形式,在 utf-8 檔案中放置 bom 主要是微軟的習慣(順便提一下:把帶有 bom 的小端序 utf-16 稱作「unicode」而又不詳細說明,這也是微軟的習慣)。

bom(byte order mark)是為 utf-16 和 utf-32 準備的,用於標記位元組序(byte order)。微軟在 utf-8 中使用 bom 是因為這樣可以把 utf-8 和 ascii 等編碼明確區分開,但這樣的檔案在 windows 之外的作業系統裡會帶來問題。

* * *

形如——

&#dddd;

&#xhhhh;

&#name;

——的一串字元是 html、xml 等 sgml 類語言的轉義序列(escape sequence)。它們不是「編碼」。

以 html 為例,這三種轉義序列都稱作 character reference:

前兩種是 numeric character reference(ncr),數字取值為目標字元的 unicode code point;以「&#」開頭的後接十進位制數字,以「&#x」開頭的後接十六進製制數字。

後一種是 character entity reference,後接預先定義的 entity 名稱,而 entity 宣告了自身指代的字元。

從 html 4 開始,ncr 以 unicode 為準,與文件編碼無關。

「中國」二字分別是 unicode 字元 u+4e2d 和 u+56fd,十六進製制表示的 code point 數值「4e2d」和「56fd」就是十進位制的「20013」和「22269」。所以——

中國中國

——這兩種 ncr 寫法都會在顯示時轉換為「中國」二字。

ncr 可以用於轉義任何 unicode 字元,而 character entity reference 很受限,參見 html 4 和 html5 中已有定義的字元列表。

字符集與編碼

前言 今天notepad 檢視測試傳過來的乙個log,開啟後竟然有部分亂碼,無法檢視完整資訊,嘗試更改編碼後仍未能解決,同事告知使用瀏覽器開啟或許可以,於是搗鼓一下,使用瀏覽器開啟並選擇編碼unicode utf 8 後終於正常顯示,順利解決問題。亂碼顯示的問題以前也經常遇到,從未認真對待過,剛好稱...

字符集與編碼

乙個位元 bit 可以是0,或者是1,8個位元 bit 組成乙個位元組 byte 全為0時代表數字0,全為1時代表數字255。乙個位元組可以表示256個數字,兩個位元組可以表示65536個數字。更多的位元組,可以有更多的組合,就可以表示更大的數值範圍。整數可以這麼存,那字元呢?一堆二進位制的0和1,...

字符集與字元編碼

字符集 字符集是各種文字和符號的總稱,也就是多個字元的集合,而常見的字符集有 ascii字符集 iso 8859字符集 gb 2312字符集 big 5字符集 gbi 8030字符集 unicode字符集等。計算機要能夠識別和儲存各種字元,就要對各種字符集進行字元編碼。字元編碼 編碼和字符集不同,字...