欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

細(xì)說ASCII、GB2312/GBK/GB18030、Unicode、UTF-8/UTF-16/UTF-32編碼

 更新時間:2023年09月11日 10:53:38   作者:jackletter  
本文主要介紹了細(xì)說ASCII、GB2312/GBK/GB18030、Unicode、UTF-8/UTF-16/UTF-32編碼,詳細(xì)的介紹了這些編碼的知識,具有一定的參考價(jià)值,感興趣的可以了解一下

1. 最簡單的ASCII碼。

ASCII碼使用1個字節(jié)記錄了128個常用的字符(ASCII規(guī)定第一個bit位固定為0,2^7=128),包含控制字符(如:鍵盤的空格、Tab鍵),以及打印字符(如:數(shù)字、英文字母等)。看下面的表格:

2. 漢字編碼,從GB2312說起

1980年,為了使每個漢字有一個全國統(tǒng)一的代碼,我國頒布了漢字編碼的國家標(biāo)準(zhǔn):GB2312-80《信息交換用漢字編碼字符集》基本集,這個字符集是我國中文信息處理技術(shù)的發(fā)展基礎(chǔ),也是國內(nèi)所有漢字系統(tǒng)的統(tǒng)一標(biāo)準(zhǔn)。

在這個標(biāo)準(zhǔn)中,我們規(guī)定使用兩個字節(jié)表示一個字符,又為了兼容ASCII碼,規(guī)定每個字節(jié)的首bit位固定為1。這樣最終編碼后的范圍是: 0xA1A1 - 0xFEFE 共94*94=8836個碼位 ),其中收錄了漢字6763個(其中一級漢字3755,二級漢字3008個),覆蓋率達(dá)到了99.75% 。

其實(shí),在GB2312中還有區(qū)位表的概念:將所有的字符都分為94區(qū),每區(qū)又有94位,

  • 01-09 區(qū)為特殊符號
  • 10-15 區(qū)為用戶自定義符號區(qū)(未編碼)
  • 16-55 區(qū)為一級漢字,按拼音排序
  • 56-87 區(qū)為二級漢字,按部首/筆畫排序
  • 88-94 區(qū)為用戶自定義漢字區(qū)(未編碼)

.示例如下:

可以通過這里查看完整的區(qū)位碼列表:《區(qū)位碼全表》

實(shí)際計(jì)算機(jī)存儲的時候肯定不是按照區(qū)位碼存的(還要避開ASCII的字符嘛),所以GB2312的存儲規(guī)則如下:

注意:上面的“a”不是ASCII中的a,而是GB2312中的“a”。

另外,我們知道ASCII碼的"a"其實(shí)就是0x61(即:97,01000001)?;谝陨先齻€字符的分析,我們新建一個文本文件并輸入:“aa啊”,并另存為“ANSI”編碼(其實(shí)就是GBK編碼,GBK兼容GB2312,這里就把GBK當(dāng)做GB2312),如下:

保存后,我們換個軟件打開,觀察下16進(jìn)制,這里我使用editplus,如下:

這里實(shí)驗(yàn)的結(jié)果和我們分析的結(jié)果正好一致。

0x61:表示ASCII中的a

0xA3E1:表示GB2312中的a

0xB0A1:表示漢字“a”.

注意:現(xiàn)在已經(jīng)不用區(qū)位碼表示了,也不用再考慮區(qū)位碼到二進(jìn)制存儲的轉(zhuǎn)換了。后面的GBK編碼就是直接在GB2312的二進(jìn)制存儲上做的擴(kuò)展。

3. 全角和半角?

對于英文字母和部分標(biāo)點(diǎn)符號有全角和半角的區(qū)別,這是因?yàn)檫@些字母和符號在ASCII中已經(jīng)定義了一遍,但GB2312中又把這些字母和符號重新定義了一遍(應(yīng)該是因?yàn)橹形呐虐骘@示不同吧),所以為了區(qū)分字母和標(biāo)點(diǎn)符號究竟是指ASCII中的還是GB2312中的,出現(xiàn)了全角和半角的說法。

  • 半角:指ASCII中的字符;
  • 全角:指GB2312中的字符;

而對于漢字來說,是沒有全角和半角的區(qū)別的,因?yàn)锳SCII中本就沒有漢字。

4. GBK編碼

GBK全稱《漢字內(nèi)碼擴(kuò)展規(guī)范》(GBK即“國標(biāo)”、“擴(kuò)展”漢語拼音的第一個字母,英文名稱:Chinese Internal Code Specification) ,中華人民共和國全國信息技術(shù)標(biāo)準(zhǔn)化技術(shù)委員會1995年12月1日制訂。

指定它的原因?

雖然GB2312中已覆蓋了99.75% 的漢字,但仍然有不少生僻字不在規(guī)范里面,作為計(jì)算機(jī)標(biāo)準(zhǔn)不能漏掉這些。

編碼特點(diǎn):

  • GBK編碼,是在GB2312-80標(biāo)準(zhǔn)基礎(chǔ)上的內(nèi)碼擴(kuò)展規(guī)范,使用了雙字節(jié)編碼方案,其編碼范圍從8140至FEFE(剔除xx7F),共23940個碼位,共收錄了21003個漢字,完全兼容GB2312-80標(biāo)準(zhǔn),支持國際標(biāo)準(zhǔn)ISO/IEC10646-1和國家標(biāo)準(zhǔn)GB13000-1中的全部中日韓(CJK)漢字,并包含了BIG5編碼中的所有漢字;
  • GBK編碼方案于1995年10月制定, 1995年12月正式發(fā)布,中文版的WIN95、WIN98、WINDOWS NT以及WINDOWS 2000、WINDOWS XP、WIN 7等都支持GBK編碼方案;

GBK對應(yīng)的區(qū)位碼?

從上面GBK的描述中,沒有發(fā)現(xiàn)區(qū)位碼的信息,沒錯,GBK是《漢字內(nèi)碼擴(kuò)展規(guī)范》,也就是說GBK不再使用區(qū)位碼,而是直接對GB2312的轉(zhuǎn)儲二進(jìn)制進(jìn)行的擴(kuò)展。

GBK是如何擴(kuò)展的GB2312,為什么GB2312最多存儲8836個碼位,而GBK可以存儲23940個?

GBK在擴(kuò)展GB2312的時候,移除了第二個字節(jié)首bit位必須為1的限制,且又做了其他擴(kuò)展,所以GBK的編碼范圍是:0x8140 - 0xFEFE,最多能表示的碼位: (0xFE-0x81+1)*(0xFE-0x40+1) => 126*191=24066

然后,GBK又規(guī)定去除0x xx7F 一條線,所以GBK最終表示 126*190=23940 個碼位,共收入 21886 個漢字和圖形符號,其中漢字(包括部首和構(gòu)件)21003 個,圖形符號 883 個。

5. GB18030編碼

隨著計(jì)算機(jī)的普及,我國后來又在GBK上擴(kuò)展字符,這被稱為GB18030,如:GB18030-2000(2000年發(fā)布),GB18030-2005(2005年發(fā)布),同時兼容ASCII、GB2312、GBK、基本兼容Unicode,特點(diǎn)如下:

  • 采用變長多字節(jié)編碼,每個字可以由1個、2個或4個字節(jié)組成。;
  • 編碼空間龐大,最多可定義161萬個字符;
  • 基本完全支持Unicode,無需動用造字區(qū)即可支持中國國內(nèi)少數(shù)民族文字、中日韓和繁體漢字以及emoji等字符;

另外,GB18030在微軟視窗系統(tǒng)中的代碼頁為54936。

6. Big5

已被GBK包含。

Big5,又稱為大五碼或五大碼,是使用繁體中文(正體中文)社區(qū)中最常用的電腦漢字字符集標(biāo)準(zhǔn),共收錄13,060個漢字。

7. 大端存儲和小端存儲

參考:《大小端(數(shù)據(jù)在內(nèi)存中的存儲)

如果有一個編碼單元需要用大于1個字節(jié)表示,那么要說明這個編碼單元放在這幾個字節(jié)內(nèi)的順序是怎樣的。

比如說,int類型占用四個字節(jié),那么這四個字節(jié)就是一個編碼單元,內(nèi)存中這四個字節(jié)排列如下:

小端存儲如下(int i=0x00000001; //數(shù)字1):

大端存儲如下(int i=0x00000001; //數(shù)字1):

如果我們在調(diào)試中觀察內(nèi)存(使用c++)就能觀察到效果了:

如果想使用c#看,需要使用unsafe模式,先設(shè)置工程屬性:

然后代碼如下:

8. Unicode

Unicode是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。Unicode用數(shù)字0-0x10FFFF來映射這些字符,最多可以容納1114112個字符,或者說有 1114112個碼位(17*256*256=1114112) 。碼位就是可以分配給字符的數(shù)字。

Unicode的學(xué)名是"Universal Multiple-Octet Coded Character Set",簡稱為UCS。UCS可以看作是"Unicode Character Set"的縮寫。

前面提到從ASCII、GB2312、GBK到GB18030的編碼方法是向下兼容的。 而Unicode只與ASCII兼容,與GB碼不兼容。 例如“漢”字的Unicode編碼是6C49,而GB碼是BABA。

Unicode 在1990年開始研發(fā),1994年正式公布。2005年3月31日推出的Unicode 4.1.0。2020年3月10日推出的Unicode 13.0.0。

Unicode 13.0.0的官方文檔:https://www.unicode.org/versions/Unicode13.0.0/UnicodeStandard-13.0.pdf

Unicode的編碼范圍:

完整的范圍,請參考:《百度百科:統(tǒng)一碼》

0000-007F:C0控制符及基本拉丁文 (C0 Control and Basic Latin):也即ASCII碼
0080-00FF:C1控制符及拉丁文補(bǔ)充-1 (C1 Control and Latin 1 Supplement)
0100-017F:拉丁文擴(kuò)展-A (Latin Extended-A)
0180-024F:拉丁文擴(kuò)展-B (Latin Extended-B)
0250-02AF:國際音標(biāo)擴(kuò)展 (IPA Extensions)
02B0-02FF:空白修飾字母 (Spacing Modifiers)
…此處省略
4E00-9FFF:CJK 統(tǒng)一表意符號 (CJK Unified Ideographs):中文漢字大多在這個區(qū)
…此處省略
10000–1FFFF: 第1輔助平面,多文種補(bǔ)充平面(Supplementary Multilingual Plane, SMP) [2]
20000–2FFFF: 第2輔助平面,表意文字補(bǔ)充平面(Supplementary Ideographic Plane, SIP) [2]
30000–3FFFF: 第3輔助平面,表意文字第三平面(Tertiary Ideographic Plane, TIP)
40000–DFFFF:第4-13輔助平面,尚未使用
E0000–EFFFF: 第14輔助平面,特別用途補(bǔ)充平面(Supplementary Special-purpose Plane, SSP)
F0000–FFFFF:第15輔助平面,保留作為私人使用區(qū)(Private Use Area, PUA)
100000–10FFFF:第16輔助平面,保留作為私人使用區(qū)(Private Use Area, PUA)

9. Unicode中的Emoji表情

由于Emoji符號是互聯(lián)網(wǎng)文化的產(chǎn)物,所以它在Unicode表的后面部分,以下是部分Emoji表情在Unicode表中的排列:

完整的列表,參見Unicode官方文檔:《Full Emoji List, v13.1

10. UCS-2和UTF-16、UCS-4和UTF-32、UTF-8

上節(jié)說到Unicode統(tǒng)一了世界字符的編碼標(biāo)準(zhǔn),但是沒有提到這些字符應(yīng)該怎樣轉(zhuǎn)儲到計(jì)算機(jī)中。

Unicode中包含1個字節(jié)(如:ASCII碼)、兩個字節(jié)(如:中文)和三個字節(jié)(如:第一輔助平面)的長度,為了將Unicode存儲到計(jì)算機(jī)中出現(xiàn)了 UCS-2 、 UCS-4 、 UTF-16 、 UTF-32 UTF-8 幾種算法。其中 UTF-8 已成事實(shí)上的流行者。

UCS-2 和 UTF-16編碼方式

UCS-2 的編碼固定占用2個字節(jié),它包含65536個編碼空間。但固定的兩個字節(jié)不足以覆蓋所有的Unicode字符,于是UTF-16誕生了,與UCS-2一樣,它使用兩個字節(jié)為全世界最常用的63K字符編碼,不同的是,它使用4個字節(jié)對不常用的字符進(jìn)行編碼。UTF-16屬于變長編碼。

UCS-4 和 UTF-32編碼方式

UCS-4的編碼固定占用4個字節(jié),編碼空間為0x00000000 - 0x7FFFFFFF(可以編碼20多億個字符)。但實(shí)際使用范圍并不超過0x10FFFF,并且為了兼容Unicode標(biāo)準(zhǔn),ISO也承諾將不會為超出0x10FFFF的UCS-4編碼賦值。由此UTF-32編碼被提出來了,它的編碼值與UCS-4相同,只不過其編碼空間被限定在了0~0x10FFFF之間。因此也可以說:UTF-32是UCS-4的一個子集。

UTF-8

也是使用變長字節(jié)表示(1-4個字節(jié)表示)。根據(jù) Unicode 編號的大小,編號小的使用的字節(jié)就少,編號大的使用的字節(jié)就多。使用的字節(jié)個數(shù)從 1 到 4 個不等。UTF-8 的編碼規(guī)則是:

  • ① 對于單字節(jié)的符號,字節(jié)的第一位設(shè)為 0,后面的7位為這個符號的 Unicode 碼,。
  • ② 對于n字節(jié)的符號 (n>1),第一個字節(jié)的前 n 位都設(shè)為 1,第 n+1 位設(shè)為 0,后面字節(jié)的前兩位一律設(shè)為 10,剩下的沒有提及的二進(jìn)制位,全部為這個符號的 Unicode 碼 。

UTF-8編碼實(shí)例:

嚴(yán)的 Unicode 是4E25(100111000100101),根據(jù)上表,可以發(fā)現(xiàn)4E25處在第三行的范圍內(nèi)(0000 0800 - 0000 FFFF),因此嚴(yán)的 UTF-8 編碼需要三個字節(jié),即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,從嚴(yán)的最后一個二進(jìn)制位開始,依次從后向前填入格式中的x,多出的位補(bǔ)0。這樣就得到了,嚴(yán)的 UTF-8 編碼是11100100 10111000 10100101,轉(zhuǎn)換成十六進(jìn)制就是E4B8A5。

11. UTF-16 LE、UTF-16 BE、UTF-32 LE和UTF-32 BE

我們在記事本另存為的時候還能看到UTF-16 LE 和 UTF-16 BE的選項(xiàng),這是因?yàn)樵谥贫║TF-16編碼的時候允許自己指定字節(jié)的存放順序,這和上面說的大小端存儲是一個意思。

UTF-32的和UTF-16一樣也有這個特點(diǎn)。

而GBK和UTF-8均沒有大小端存儲的區(qū)別,因?yàn)樗鼈兌际前凑兆止?jié)的順序從低位開始排列的。

以漢字 “嚴(yán)” 為例,它的Unicode編碼為4E25,我們打開記事本,寫入漢字 “嚴(yán)” ,并另存為 UTF-16 LE:

然后,我們使用editplus打開,觀察它的16進(jìn)制如下:

如果,我們另存為UTF-16 BE,那么16進(jìn)制顯示如下:

12. UTF-8和UTF-8-BOM

雖然UTF-8沒有大小端存儲的區(qū)別,但是我們會看到UTF-8-BOM類型的編碼,那么有BOM和無BOM的啥區(qū)別呢?

帶BOM的會在文本的前面添加 EF BB BF 三個字節(jié)以表示這是UTF-8編碼。

還是以漢字“嚴(yán)”為例,我們知道“嚴(yán)”的UTF-8編碼為:0xE4B8A5,下面我們打開記事本,輸入漢字“嚴(yán)”,將它保存為UTF-8編碼:

然后,用editplus打開觀察16進(jìn)制,如下:

如果,我們將它保存為帶BOM的UTF-8,然后觀察16進(jìn)制,會發(fā)現(xiàn)在首部多了3個字節(jié),如下:

雖然,帶BOM的UTF-8編碼能更好的表示文本文件,但帶bom的shell腳本在linux執(zhí)行的時候卻會報(bào)錯,所以除非必須,不要使用帶BOM的UTF-8編碼。

13. 如何根據(jù)文本首字節(jié)確定其編碼方式

首先,由于GBK不存在字節(jié)序,文本前端不需要加字節(jié)說明,不帶BOM的UTF-8編碼文本也不需要加字節(jié)說明,所以下面的判斷只能是識別已經(jīng)指明編碼格式的文本。

14. 編碼總結(jié)(字符集和字符編碼)

區(qū)分字符集和字符編碼的概念:

  • 字符集:定義了一套字符,比如:GB2312、GBK等定義了一整套的中文符號,Unicode定義了全世界的符號;
  • 字符編碼:將一個字符集轉(zhuǎn)儲成二進(jìn)制的規(guī)則,比如:GB2312、GBK自帶編碼規(guī)則,可以將字符轉(zhuǎn)儲成二進(jìn)制,而UTF-8、UTF-16則是Unicode的編碼規(guī)則,負(fù)責(zé)將Unicode中的字符轉(zhuǎn)儲成二進(jìn)制。

如下圖所示:

15. 如何查看字符對應(yīng)的各種類型編碼?

方法一: 直接在網(wǎng)站:https://www.qqxiuzi.cn/bianma/zifuji.php 上搜索即可得某個字符的 ASCII、GB2312、BIG-5、GBK、GB18030、Unicode編碼;比如,大寫英文字母“W”:

又比如漢字“王”:

還有emoji表情:

方法二:上面雖然有常規(guī)的編碼轉(zhuǎn)換,但是沒有關(guān)于UTF-16、UTF-8的轉(zhuǎn)換,下面借助c#程序得到字符的UTF-16和UTF-8編碼:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine($"W Unicode =>{ConvertToHex("W", "Unicode")}");
        Console.WriteLine($"W UTF-16 =>{ConvertToHex("W", "UTF-16")}");
        Console.WriteLine($"W UTF-32 =>{ConvertToHex("W", "UTF-32")}");
        Console.WriteLine($"W UTF-8 =>{ConvertToHex("W", "UTF-8")}");
        Console.WriteLine($"王 Unicode =>{ConvertToHex("王", "Unicode")}");
        Console.WriteLine($"王 UTF-16 =>{ConvertToHex("王", "UTF-16")}");
        Console.WriteLine($"王 UTF-32 =>{ConvertToHex("王", "UTF-32")}");
        Console.WriteLine($"王 UTF-8 =>{ConvertToHex("王", "UTF-8")}");
        Console.WriteLine($"?? Unicode =>{ConvertToHex("??", "Unicode")}");
        Console.WriteLine($"?? UTF-16 =>{ConvertToHex("??", "UTF-16")}");
        Console.WriteLine($"?? UTF-32 =>{ConvertToHex("??", "UTF-32")}");
        Console.WriteLine($"?? UTF-8 =>{ConvertToHex("??", "UTF-8")}");
    }
    private static string ConvertToHex(string str, string encodingStr)
    {
        var encoding = System.Text.Encoding.GetEncoding(encodingStr);
        return ConvertToHex(str, encoding);
    }
    private static string ConvertToHex(string str, Encoding encoding)
    {
        var bs = encoding.GetBytes(str);
        return "0x" + string.Join("", bs.ToList().Select(i => i.ToString("X2")));
    }
}

打印的結(jié)果:

這里有亂碼,是因?yàn)榭刂婆_使用的ANSI編碼,即:GBK編碼,GBK中沒有emoji的字符,所有顯示亂碼。

方法三:我們也可以借助notepad++的16進(jìn)制插件或editplus等編輯器查看,參照:《新版Notepad++加十六進(jìn)制查看的插件HexEditor

最終,我們總結(jié)得出英文大寫字母“M”、漢字“王”、emoji表情“??”的各個編碼如下:

字符ASCIIGB2312Big5GBKGB18030UnicodeUTF-16UTF-8
W0x570x570x570x570x570x570x570x57
0xCDF50xA4FD0xCDF50xCDF50x738B0x8B730xE78E8B
??0x9439FC360x1F60010x3DD800DE0xF09F9880

16. ANSI編碼、代碼頁為何物?

先說下代碼頁:

可以把代碼頁當(dāng)做字符集編碼的別名,比如:

936:代表中文簡體;437:代表ASCII;65001:代表UTF-8;

完整的代碼頁列表,參考微軟網(wǎng)站:《代碼頁標(biāo)識符》

再來看ANSI:

參考:《ANSI是什么編碼?

在window環(huán)境下經(jīng)常見到 “ANSI”標(biāo)志,如:

乍一看,ANSI和ASCII好像,但它們不是同一個意思。

ANSI編碼解釋:

ANSI 并不是某一種特定的字符編碼,它表示的是你的系統(tǒng)中設(shè)置的國家區(qū)域?qū)?yīng)的字符編碼。比如你的美國同事Bob的系統(tǒng)中ANSI編碼其實(shí)是ASCII編碼(ASCII編碼不能表示漢字,所以漢字為亂碼),而你的系統(tǒng)中(“漢字”正常顯示)ANSI編碼其實(shí)是GBK編碼,而韓文系統(tǒng)中(“???”正常顯示)ANSI編碼其實(shí)是EUC-KR編碼。

我們打開cmd窗口,查看cmd用的什么字符集編碼:

如何修改window操作系統(tǒng)的區(qū)域?

看下圖:

當(dāng)我們把區(qū)域改成英語(美國)后,重啟電腦,再次打開命令行,如下:

然后,打開window記事本,輸入漢字“什么”,然后保存,再次打開,發(fā)現(xiàn)正常顯示中文,但這里能正常顯示卻是因?yàn)楸4娴母袷绞荱TF-8,如下:

當(dāng)我們把它保存成ANSI時:

這里提示我們,因?yàn)槔锩嬗蠻nicode格式的字符(Unicode中有中文字符),而此時的ANSI表示的是ASCII碼(已設(shè)置區(qū)域?yàn)橛⒄Z美國),所以會提示我們會有字符丟失的風(fēng)險(xiǎn),點(diǎn)擊確定繼續(xù):

參考:

《編碼標(biāo)準(zhǔn)-GB2312 GBK GB18030》

《字符編碼筆記:ASCII,Unicode 和 UTF-8》

《字體編輯用中日韓漢字Unicode編碼表》

《程序員趣味讀物:談?wù)刄nicode編碼》

到此這篇關(guān)于細(xì)說ASCII、GB2312/GBK/GB18030、Unicode、UTF-8/UTF-16/UTF-32編碼的文章就介紹到這了,更多相關(guān)ASCII GB2312 Unicode UTF-8內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

最新評論