最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【硬核技術(shù)文】韋東山:字符的編碼方式

2020-07-31 12:07 作者:韋東山  | 我要投稿

作者:韋東山

自從上次發(fā)布“Framebuffer應(yīng)用編程”視頻后,

我們花了10多天調(diào)試STM32MP157板子,4.19內(nèi)核、5.4內(nèi)核全部調(diào)試通過(guò)!

在調(diào)試過(guò)程中,編寫(xiě)了不少文檔,到時(shí)整理后再發(fā)布給大家,也許可以錄一個(gè)項(xiàng)目:

怎么把廠家SDK移植到到自己的板子?

這是以后的事了,

從今天開(kāi)始,韋老師又繼續(xù)錄制、發(fā)布視頻了。

今天發(fā)布文章:字符的編碼方式,視頻同步錄制中。

6.1 字符的編碼方式

6.1.1 編碼與字體

在計(jì)算機(jī)上,我們看到的字符“A”可能長(zhǎng)這樣:



也可能長(zhǎng)這樣:



對(duì)于同一個(gè)TXT文件中的內(nèi)容,你在Notepad上選擇不同字體時(shí),字符顯示的形狀不一樣。

所以TXT文件中保存的是字符的核心:它的編碼值。而Notepad上顯示時(shí),這些字符對(duì)應(yīng)什么樣的形狀態(tài),這是由字符文件決定的。編碼值,字體是兩個(gè)不一樣的東西,比如A的編碼值是0x41,但是在屏幕上顯示出來(lái)時(shí)可以使用不同的形狀。


什么叫編碼?就是一個(gè)字符用什么數(shù)字來(lái)表示。在計(jì)算機(jī)里一切都是用數(shù)字來(lái)表示,比如字符A,用0x01還是0x02來(lái)表示它?我們使用0x41來(lái)表示它。當(dāng)你去打開(kāi)一個(gè)TXT文件時(shí),發(fā)現(xiàn)里面含有數(shù)值0x41,你就知道了:哦,這里有一個(gè)字符A。


一個(gè)字符用哪個(gè)數(shù)字來(lái)表示?有很多標(biāo)準(zhǔn),舉例講解。

1. ASCII

是“American Standard Code for Information Interchange”的縮寫(xiě),美國(guó)信息交換標(biāo)準(zhǔn)代碼。

電腦畢竟是西方人發(fā)明的,他們常用字母就26個(gè),區(qū)分大小寫(xiě)、加上標(biāo)點(diǎn)符號(hào)也沒(méi)超過(guò)127個(gè),每個(gè)字符用一個(gè)字節(jié)來(lái)表示就足夠了。一個(gè)字節(jié)的7位就可以表示128個(gè)數(shù)值,在ASCII碼中最高位永遠(yuǎn)是0。

字符和數(shù)值的對(duì)應(yīng)關(guān)系可以參考:baike.baidu.com/item/AS

下面摘錄部分給大家一個(gè)印象:





2. ANSI

強(qiáng)烈建議閱讀:cnblogs.com/malecrab/p/

使用記事本保存文件時(shí),可以選擇“ANSI”編碼,卻沒(méi)有“ASCII”,各下圖所示。怎么回事?



ASNI是ASCII的擴(kuò)展,向下包含ASCII。對(duì)于ASCII字符仍以一個(gè)字節(jié)來(lái)表示,對(duì)于非ASCII字符則使用2字節(jié)來(lái)表示。并沒(méi)有固定的ASNI編碼,它跟“本地化”(locale)密切相關(guān)。比如在中國(guó)大陸地區(qū),ANSI的默認(rèn)編碼是GB2312;在港澳臺(tái)地區(qū)默認(rèn)編碼是BIG5。以數(shù)值“0xd0d6”為例,對(duì)于GB2312編碼它表示“中”;對(duì)于BIG5編碼它表示“笢”。所以對(duì)于ANSI編碼的TXT文件,如果你打開(kāi)它發(fā)現(xiàn)亂碼,那么還得再次細(xì)分它的具體編碼。

比如對(duì)于一個(gè)TXT文件,里面的數(shù)值如下:




使用Notepad打開(kāi)后,選擇不同的編碼(或稱為字符集),有不一樣的顯示,如下:


這僅僅是在中國(guó)地區(qū)就出現(xiàn)這些不兼容的問(wèn)題。對(duì)于不同國(guó)家,它們默認(rèn)的ANSI編碼各不相同,所以同一個(gè)TXT文件在不同國(guó)家就很有可能出現(xiàn)亂碼。

根本的原理在于沒(méi)有“統(tǒng)一的編碼”,那解決方法自然就是使用“統(tǒng)一的編碼”:UNICODE。

3. UNICODE

在ANSI標(biāo)準(zhǔn)中,很多種文字都有自己的編碼標(biāo)準(zhǔn),漢字簡(jiǎn)體字有GB2312、繁體字有BIG5,這難免同一個(gè)數(shù)值對(duì)應(yīng)不同字符。比如數(shù)值“0xd0d6”,對(duì)于GB2312編碼它表示“中”;對(duì)于BIG5編碼它表示“笢”。這造成了使用ANSI編碼保存的文件,不適合跨地區(qū)交流。

UNICODE編碼就是解決這類問(wèn)題:對(duì)于地球上任意一個(gè)字符,都給它一個(gè)唯一的數(shù)值。

UNICODE仍然向下兼容ASCII,但是對(duì)于其他字符會(huì)有對(duì)應(yīng)的數(shù)值,比如對(duì)于“中”、“笢”,它們的數(shù)值分別是:0x4e2d、0x7b22

UNICODE中的數(shù)值范圍是0x0000至0x10FFFF,有1,114,111即100多萬(wàn)個(gè)數(shù)值,可以表示100多萬(wàn)個(gè)字符,足夠地球人使用了。


6.1.2 編碼實(shí)現(xiàn)

所謂編碼實(shí)現(xiàn),就是對(duì)于一個(gè)數(shù)值,怎么表示它。這很奇怪,數(shù)值還能怎么表示?比如“中”的UNICODE值是0x4e2d,在TXT文件中怎么表示0x4e2d?直接寫(xiě)入0x4e2d?不行!

比如在TXT文件中寫(xiě)入2字節(jié)數(shù)據(jù)“0x2d 0x4e”,它可以用來(lái)表示“中”字嗎?不能!它們對(duì)應(yīng)ASCII字符“-N”。

問(wèn)題的關(guān)鍵在于:怎么斷字。在TXT文件中,2字節(jié)數(shù)據(jù)“0x2d 0x4e”是作為一個(gè)整體看待,還是拆成2部分看待?

所以,需要用一定的技巧來(lái)表示數(shù)值,這就對(duì)應(yīng)不同的編碼實(shí)現(xiàn)。


現(xiàn)在我們知道:

1. ASCII編碼中使用一個(gè)字節(jié)來(lái)表示一個(gè)字符,只用到其中的7位,最高位恒為0;

2. ANSI編碼中,對(duì)于ASCII字符仍使用一個(gè)字節(jié)來(lái)表示(BIT7是0),對(duì)于非ASCII字符一般使用2個(gè)字節(jié)來(lái)表示,非ASCII字符的數(shù)值BIT7都是1。

3. UNICODE:這就有點(diǎn)復(fù)雜了,下面一一講解。


先用記事本新建3個(gè)文件:utf-16_le.txt、utf-16_be.txt、utf-8.txt、bom_utf-8.txt,里面的內(nèi)容都是“ab中”,保存時(shí)編碼分別選擇“UTF-16 LE”、“UTF-16 BE”、“UTF-8”、“帶有BOM的UTF-8”,下圖是其中一個(gè)例子:




怎么表示一個(gè)UNICODE數(shù)值?

1. 使用3個(gè)字節(jié)表示一個(gè)UNICODE

不,太浪費(fèi)。

UNICODE的最大值是0x10FFFF,那使用3個(gè)字節(jié)來(lái)表示一個(gè)UNICODE數(shù)值?這當(dāng)然是很省事的方法,但是會(huì)造成浪費(fèi),比如字符A的UNICOCDE值是0x41,難道也用“0x41 0x00 0x00”這3個(gè)字節(jié)來(lái)表示?

2. UCS-2 Little endian/UTF-16 LE

每個(gè)UNICODE值用3字節(jié)來(lái)表示有點(diǎn)浪費(fèi),那只用2字節(jié)呢?它可以表示2^16=65536個(gè)字符,全世界常用的字符都可以表示了。

Little endian表示小字節(jié)序,數(shù)值中權(quán)重低的字節(jié)放在前面,比如字符“ab中”在TXT文件中的數(shù)值如下,其中的“a”使用“0x61 0x00”兩字節(jié)表示;“b”使用“0x62 0x00”兩字節(jié)表示;“中”使用“0x4e 0x2d”兩字節(jié)表示。文件開(kāi)頭的“0xff 0xfe”表示“UTF-16 LE”。



3. UCS-2 Big endian/UTF-16 BE

Big endian表示小字節(jié)序,數(shù)值中權(quán)重低的字節(jié)放在后面,比如字符“ab中”在TXT文件中的數(shù)值如下,其中的“a”使用“0x00 0x61”兩字節(jié)表示;“b”使用“0x00 0x62”兩字節(jié)表示;“中”使用“0x2d 0x4e”兩字節(jié)表示。文件開(kāi)頭的“0xfe 0xff”表示“UTF-16 BE”。




4. UTF8

在上面2種方法中,每一個(gè)UNICODE使用2字節(jié)來(lái)表示,這有3個(gè)缺點(diǎn):表示的字符數(shù)量有限、對(duì)于ASCII字符有空間浪費(fèi)、如果文件中有某個(gè)字節(jié)丟失,這會(huì)使得后面所有字符都因?yàn)殄e(cuò)位而無(wú)法顯示。

使用UTF8可以解決上述所有問(wèn)題。UTF8是變長(zhǎng)的編碼方法,有2種UTF8格式的文件:帶有頭部、不帶頭部。先舉例,看下圖:



對(duì)于其中的ASCII字符,在UTF8文件中直接用其ASCII碼來(lái)表示,比如上圖中的0x61表示字符a、0x62表示字符b。上圖中的3個(gè)字節(jié)“0xe4 0xb8 0xad”表示的數(shù)值是0x4e2d,對(duì)應(yīng)“中”的UNICODE碼。

對(duì)于非ASCII字符,使用變長(zhǎng)的編碼:每一個(gè)字節(jié)的高位都自帶長(zhǎng)度信息。請(qǐng)看下圖:



上圖中,0xe4的二進(jìn)制是“11100100”,高位有3個(gè)1,表示從當(dāng)前字節(jié)起有3字節(jié)參與表示UNICODE;

0xb8的二進(jìn)制是“10111000”,高位有1個(gè)1,表示從當(dāng)前字節(jié)起有1字節(jié)參與表示UNICODE;

0xad的二進(jìn)制是“10101101”,高位有1個(gè)1,表示從當(dāng)前字節(jié)起有1字節(jié)參與表示UNICODE;

除去高位的“1110”、“10”、“10”后,剩下的二進(jìn)制數(shù)組合起來(lái)得到“01001110001101”,它就是0x4e2d,即“中”的UNICODE值。

使用UTF8編碼時(shí),即使TXT文件中丟失了某些數(shù)據(jù),也只會(huì)影響到當(dāng)前字符的顯示,后面的字符不受影響。

**加weixin 13923404017 (暗號(hào):b站)? 進(jìn)討論氛圍濃厚的技術(shù)交流群

【硬核技術(shù)文】韋東山:字符的編碼方式的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
利川市| 长乐市| 青州市| 射阳县| 龙山县| 临澧县| 延津县| 沙洋县| 宣城市| 赫章县| 淮滨县| 永泰县| 万州区| 青田县| 八宿县| 博白县| 桓台县| 崇阳县| 克东县| 顺昌县| 万年县| 巩留县| 华蓥市| 漳州市| 古田县| 柳州市| 岢岚县| 榆树市| 若尔盖县| 利津县| 新蔡县| 宣化县| 百色市| 丁青县| 丹阳市| 奈曼旗| 神农架林区| 西峡县| 马龙县| 凤阳县| 平谷区|