編碼(1) unicode,utf 8和其他編碼

2021-07-25 05:05:18 字數 3311 閱讀 3817

1. 字符集:

ascii字符集,最初的字符集,對應了ansi檔案編碼,乙個字元用乙個位元組表示,嚴格來說這個時候字符集和文字檔案的編碼並沒有必要作為單獨的概念加以區分;從此也可以看出,原來是沒有中間的字符集的抽象的。字符集就是編碼方式,編碼解碼直接對著字符集的對映表即可。二者是乙個概念。

西歐字符集、日韓、港澳台、國標字符集等,仍然使用了ansi檔案編碼,其中部分字符集乙個字元要用兩個位元組;

unicode字符集,終於在完成了字符集層面的集大成後,開始反過頭來規定適合自己的檔案編碼(儲存為ansi會丟失大量的新增擴充套件字元),即unicode transformation format(unicode轉換格式,其中每種方案針對不同發展階段的使用情境設計,在其針對的情況下都能夠大幅度地減少常見字的空間占用):而unicode的編碼方式分為utf-8,utf-16,utf-32

歷史:[character set] 字符集歷史計算機的發明。由於乙個位元組(byte)有8位(bit),類似10101010,因此乙個基本的儲存單位能夠表示2的8次方(即256)種字元,而基本的計算機字元(所謂的半形字元,說白了是發明計算機的美國常用的字元)用128個就表示完了,所以這時候不存在任何問題,乙個位元組(計算機儲存單位)對應乙個字元(人類自然語言文字中的單位),這套字符集被稱為ascii,包括了半形英文大小寫、半形數字、半形表單符號等。閒得無聊的美國人還用多出來的一位作校驗碼,用於避免電路不穩定訊號傳輸錯誤(其實是看著浪費不順眼)。

(之所以乙個位元組不是7位,是考慮到2的整數冪,要麼4位、要麼16位,8位剛好夠用,後文會看出幸好如此,否則很難想象有預留的先見之明,畢竟研究各國文化恐怕比發明計算機還麻煩。)

後來歐洲語言的擴充。計算機的世界化過程中,歐洲緊隨其後。他們馬上發現各種注音的拉丁語系字母無法表示,因此把後128位直接用上了,128+128,皆大歡喜。

(一方面這可以理解為目光短淺,另一方面也確實沒有必要浪費更多空間。)

世界另一邊象形文本的擴充。以中文為例,雖然比歐洲稍晚,但實際上應當與歐洲理解為第二傳播梯隊同期的各自閉門造車。由於中文太多,索性用多個計算機位元組(兩個)表示乙個中文字元。為了避免與美國原始體系衝突,我們規定當乙個位元組在128以內時,還是原義;超出128的,需要與後面乙個位元組組合解讀成乙個字元。這樣128瞬間變成了128*256,完全夠用了。這套字符集命名以gb(國標)開頭,有過幾次擴充(gb2312、gbk、gb18030),相互不完全相容,與歐洲擴充套件字符集自然也不相容。注意中國人用計算機也是要處理拉丁文、日韓等文字的,所以其中並不只有中文,只是各國實現的標準不同。同期產生的還有big5(港澳台地區正體中文標準)、jis(日本)等。

(表面上看起來各國各自為營很不合理,實際上一開始就要考慮所有問題會導致各自極其不合理,而事實上各自為營的發展速度和地位上公升才是後一步的現實前提。)

世界統一標準。隨著網際網路的發展,計算機工業不再僅限於處理不同的文字,還必須用同一套方式處理。universal character set,簡稱ucs,別名unicode(實際是兩個並行起草的字符集,快弄好了才發現彼此乾脆合併了協議),應運而生。unicode包羅永珍,並預留好了無限擴充套件的方案。隨著計算機硬體發展,這種通用方案雖然略浪費空間,卻極大地節省了人的工作成本。

2. 還有一點,就是之所以unicode分成字符集和編碼方式,但是gb2312,ascii等貌似就沒有字符集。因為那個時候計算機沒有普及,需求沒有這麼大,就不用單獨抽象出乙個字符集的概念。此時編碼方式和字符集是乙個東西。無論編碼解碼,直接對照字符集的對映表就可以完成。另外,字符集其實和檔案對物理磁碟的抽象一樣。屬於後來為了方便,對字元集合和編碼分開。這樣有了中間的一層抽象,即使字符集有變化,編碼方式也不需要改變。

如果直接使用 「字串↔️字元↔️二進位制表示(編碼)」 ,會增加不同型別編碼之間轉換的複雜性。所以引入了乙個抽象層,「字串↔️字元↔️與儲存無關的表示↔️二進位制表示(編碼)」 ,這樣,可以用一種與儲存無關的形式表示字元,不同的編碼之間轉換時可以先轉換到這個抽象層,然後再轉換為其他編碼形式。在這裡,unicode 就是 「與儲存無關的表示」,utf—8 就是 「二進位制表示」。

3. unicode是字符集,沒有所謂的幾個位元組。而utf是unicode繫結的編碼方式。utf-8是1,2,3,4個位元組,utf-16是2,4個位元組,utf-32是4個位元組。各有各的好。因為8位是對大量使用英文很有優勢,這個可以節省儲存空間應該都明白。但是,如果對於那些無法用乙個位元組表示的字元使用8位,就會浪費。因為當使用變長的位元組來編碼的時候,是需要犧牲掉一部分來讓編碼器知道是應該把兩個位元組,還是單個位元組亦或者更多位元組放到一起讀的。具體可以看下面的例子。

可見,unicode字符集層面的概念,處理的是每個漢字對應的計算機編號。

做個簡單的比喻, unicode相當於中文, utf-8, utf-16等相當於 行書, 楷書, 草書等各種書寫方式.

4. 任何文字都是有編碼的。但是,如果只有英文,即使編碼不對,一般不會報錯。因為大部分編碼都是相容acsii的。

5. 之所以

content-type: text/html; charset=utf-8,

utf-8本身是檔案編碼資訊,卻寫在charset(字符集)的位置,其實是暗示了其從屬的unicode字符集系統,同時又順便指出了檔案編碼資訊(因為二者是高度繫結的關係),

6.  計算機內只能儲存101010等二進位制資料,那麼頁面上顯示的字元是如何顯示出來的呢?

一:字符集(charset)

charset = char + set,char 是字元,set是集合,charset就是字元的集合。

字符集就是是這個編碼方式涵蓋了哪些字元,每個字元都有乙個數字序號。

二:編碼方式(encoding)

編碼方式就是乙個字元要怎樣編碼成二進位制位元組序,或者反過來怎麼解析。

也即給你乙個數字序號,要編碼成幾個位元組,位元組順序如何,或者其他特殊規則。

三:字形字型(font)

根據數字序號呼叫字型儲存的字形,就可以在頁面上顯示出來了。

所以乙個字元要顯示出來,要顯示成什麼樣子要看字型檔案。

7. 編碼從總體上分為檔案層和包裝層:

保證層是對檔案層在傳輸過程中的包裝。有點類似網路分層的味道。具體看下面的附錄:

8. 再次確認,所有的short,int等都是用二的補碼表示的。也就是如果int是4個位元組,就是-2^31~2^31-1. 如果是一位,就是-128~127

9. 以後請不要在問是用unicode還是utf-8了,二者不是乙個層次的東西。也不要問unicode有幾個位元組了,它壓根沒有上限。如果有需要,一百個位元組也可以。

Nim 處理Unicode UTF 8編碼

unicode 模組提供支援處理unicode utf 8編碼。type runeimpl int rune distinct runeimpl 可以容納任何 unicode 字元 型別。rune16 distinct int16 16位 unicode 字元 proc runelen s stri...

Base64編碼 Unicode UTF 8編碼

base64編碼 64種可列印字元,表示原二進位制格式中的6bit base64編碼有一張編碼表 解碼的時候也用它 0 63的id對映到可列印字元 6bit 4 8bit 3,所以4個字元一組,表示3個8 bit二進位制子節 原二進位制子節數不為3個倍數時 原位元組缺1個,則編碼為3個字元 第3個字...

unicode編碼和utf 8編碼詳解

unicode是國際通用編碼,utf 8編碼是unicode編碼在網路之間 主要是網頁 傳輸時的一種 變通 和 橋梁 編碼。utf 8在網路之間傳輸時可以節約資料量。所以,使用作業系統無法搜尋出txt文字。按照utf 8創始人的願望 端 unicode 傳輸 utf 8 端 unicode 但是,後...