日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符集:ASCII、GB2312、GBK、GB18030、Unicode

發布時間:2025/4/5 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符集:ASCII、GB2312、GBK、GB18030、Unicode 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 字符集、代碼點、編碼的概念
    • 2 字符集發展的脈絡
      • 2.1 最早是ASCII
      • 2.2 各個國家后續推出的編碼表
      • 2.3 ANSI到底是什么編碼
    • 3 ASCII
      • 3.1 ASCII字符集簡介及其編碼的字符
      • 3.2 ASCII字符集的代碼點
      • 3.3 ASCII字符集的編碼方式
      • 3.4 擴充的ASCII編碼
    • 4 GB2312
      • 4.1 GB2312字符集簡介及其編碼的字符
      • 4.2 GB2312字符集的代碼點
      • 4.3 GB2312字符集的編碼方式
    • 5 GBK
    • 6 GB18030
    • 7 Unicode
      • 7.1 Unicode介紹
      • 7.2 UTF-8:變長的編碼規則
      • 7.3 UTF-16:變長的編碼規則
      • 7.4 UTF-32:定長的編碼規則
      • 7.5 Unicode字符存儲的字節序問題
      • 7.6 UTF-16和UTF-32的三種子風格、BOM
      • 7.7 UCS-2和UCS-4

1 字符集、代碼點、編碼的概念

任何信息存儲在計算機中,都將是無差別的0和1的序列。所以,我們要想在計算機中存儲字符,那么,我們就需要對字符進行編碼,將字符編碼為計算機可以識別的0和1的序列。編碼就是將信息從一種形式轉換為另一種形式。

字符集:
在編碼之前,我們首先要確定,我們要對哪些字符進行編碼。然后,將這些需要進行編碼的字符集合到一起,這樣就形成了我們所說的字符集。常見的字符集有:ASCII、GBK、GB2312、Unicode等等。

代碼點:
字符集中的每一個字符都會被分配一個編號,這個編號我們稱之為代碼點。
需要注意如下:在ASCII字符集中,代碼點是從0開始依次遞增的 。但是,并非所有的字符集,代碼點都是從0開始依次遞增的。

編碼:
為了在計算機中存儲字符,我們需要將字符的代碼點轉換為0和1的序列,而這個轉換的過程,我們稱之為字符編碼。

要想在計算機存儲字符,需要經過如下5個步驟:
字符 --> 代碼點 --> 編碼 --> 0和1的序列(字符的編碼) --> 存儲到計算機中。


2 字符集發展的脈絡

2.1 最早是ASCII

最早出現的字符集是ASCII。

2.2 各個國家后續推出的編碼表

歐洲:ISO-8859-1、在ASCII基礎上的擴充(擴展ASCII編碼表)。

中國: GB2312 -> GBK -> GB18030(新的兼容舊的)。

臺灣: BIG5。

日本: JIS。

2.3 ANSI到底是什么編碼

ANSI對于不同語言的操作系統對應的編碼是不同的,如下:

  • 簡體中文操作系統:GB2312。
  • 繁體中文操作系統:Big5。
  • 日文操作系統:JIS。
  • 英文操作系統:ASCII。

3 ASCII

3.1 ASCII字符集簡介及其編碼的字符


使用一個字節來映射,映射了128個字符。只占用了最高位為0的8位二進制數來進行映射。

3.2 ASCII字符集的代碼點

在ASCII字符集中,代碼點是從0開始依次遞增的。

3.3 ASCII字符集的編碼方式

直接將代碼點編碼為它所對應的8位二進制數即可。

注意: 一個字節并非一定是8位,所以,嚴格來說應該是:轉換為它所對應的1個字節長的二進制數。

3.4 擴充的ASCII編碼

歐洲:ISO-8859-1、在ASCII基礎上的擴充(擴展ASCII編碼表)。


4 GB2312

4.1 GB2312字符集簡介及其編碼的字符

包括了漢字信息交換用的基本圖形字符。GB2312兼容ASCII,由兩個大于127的字節來映射我們增加的字符。發現最高位是0,那么就可以確定這個字節映射的就是ASCII的字符,那么就只讀取一個字節,然后去查ASCII表,然后將其解析為對應的字符。發現最高位是1,那么就可以確定這個字節映射的就是GB2312的字符,那么就連續讀兩個字節,然后去查GB2312,然后將其解析為對應的字符。

4.2 GB2312字符集的代碼點

GB2312字符集中,代碼點是根據區號位號來安排的。

GB2312將字符劃分為了94個區(區號從1-94),每個區94個字符。字符在區里面的位置叫做位號(位號從1-94)。
比如:字符 <健>,它屬于第29區中的第一個字符那么,字符 <健>的區號就是29,位號就是1。

GB2312的代碼點計算方式如下:區號+32,位號+32 --> 代碼點,那么健的代碼點就是61,33。

+32的原因:
GB2312字符集除了兼容ASCII以外,它還對原ASCII中打印字符進行了2字節的編碼,就是我們平時所說的全角字符(第3區)。
全角字符在顯示和打印的時候,字符的輪廓占一個漢字的位置:

  • AAA  --> 半角
  • AAA --> 全角

為了使全角字符的位號和它所對應的半角字符在ASCII中的代碼點保持一致,以方便它們之間的互轉。所以,我們對位號+32得到最終的代碼點 。區號為什么+32?暫時不知道,哈哈哈哈。

4.3 GB2312字符集的編碼方式

由于GB2312字符集兼容ASCII,所以,原ASCII的字符仍舊按照它原來的方法進行編碼(1個字節)。GB2312采用2個字節對自身的字符進行編碼:區號轉換為二進制存入高字節中,位號轉換為二進制數存入低字節中,兩個字節的最高位固定為1

最高位固定為1的原因:
如果一個字節,它的最高位為0,那么,我們就可以判定這個字節存儲的是ASCII字符的編碼,我們就應該按照ASCII的字符編碼方法對它進行解析,得到正確的結果。如果一個字節,它的最高位為1,我們就可以判定這個字節及其后面的一個字節,存儲的是GB2312字符的編碼,我們就應該將這個字節及其后面的一個字節,按照GB2312的字符編碼方法對它進行解析,得到正確的結果。


5 GBK

隨著計算機的發展,它的普及率越來越高,它的應用場合也越來越多,而GB2312字符集中只有6763個漢字,而我們常用的漢字就有幾千個。顯然,這6763個漢字已經滿足不了越來越多的使用場合了。

因此,我們在GB2312字符集的基礎上進行了擴充,建立了GBK字符集:

  • GBK字符集 兼容 GB2312字符集(這就意味著GBK也是兼容ASCII的)
  • GBK字符集 仍然采用1個字節對原ASCII字符進行編碼,仍然采用2個字節對原GB2312字符進行編碼,采用2個字節對擴充進來的字符進行編碼。
  • GBK字符集 不要求低字節最高位固定為1。因為,它需要更多的空間來對擴充進來的字符進行編碼。

  • 6 GB18030

    隨著時間的推進,我們在GBK字符集的基礎上又創建了GB18030字符集。

  • GB18030字符集 兼容 GBK字符集(這就意味著GB18030兼容GB2312、兼容ASCII)
  • GB18030字符集 仍然采用1個字節對原ASCII字符進行編碼,仍然采用2個字節對原GB2312字符進行編碼,仍然使用2個字節對原GBK字符進行編碼。采用4個字節對擴充進來的字符進行編碼因為,它需要更多的空間來對擴充進來的字符進行編碼。
  • 兼容性: ASCII(128) --> GB2312(7445) --> GBK(21886) --> GB18030(漢字70,244)。


    7 Unicode

    Unicode標準有兩套,不過后期這兩套標準基本上是一致的。

    UNICODE協會:

    • 字符集全稱:Universal Character Encoding
    • 縮寫:UNICODE
    • 翻譯:通用字符集編碼

    ISO 10646工作組:

    • 字符集全稱:Universal Coded Character Set
    • 縮寫:UCS
    • 翻譯:通用編碼字符集
    • 標準號:ISO 10646

    7.1 Unicode介紹

    UNICODE字符集分為 17個區(標準的稱呼應該是 17個平面):

    • 區號為: 0-16(0x00 - 0x10),每個區65536個字符。
    • 位號為: 0-65535(0x0000 - 0xFFFF)。

    代碼點: 高兩位十六進制數對應的是區號、低四位十六進制數對應的是位號 。

    • 平面0的代碼點:0x00 0000 - 0x00 FFFF
    • 平面1的代碼點:0x01 0000 - 0x01 FFFF
    • 平面2的代碼點:0x02 0000 - 0x02 FFFF
    • 平面17的代碼點:0x10 0000 - 0x10 FFFF

    由此可以發現:

  • UNICODE字符集的代碼點是從0開始依次遞增的(和ASCII一致)。
  • UNICODE字符集的代碼點范圍:0x00 0000 - 0x10 FFFF。
  • 代碼點表示方法:

    • U+十六進制數字 ,比如:U+00 00FF(所以,上面表示代碼點的方法是錯誤的)。

    低0區的字符:

    • 第0區的字符是每個國家和地區的常用字符。也就是說,第0區混雜了各個國家常用的字符。
    • 第0區又叫做:基本多語種平面。

    思考:為什么這么做?
    第0區代碼點的數值較小,所對應的編碼值也較小,這就意味著第0區代碼點更節省空間(我們不一定非要采用3個字節來對Unicode進行編碼)。那么很顯然,將使用較為頻繁的常用字符分配到第0區,就意味著更加節省空間。

    UNICODE字符集的標準編碼規則是UTF-8、UTF-16、UTF-32,下面分別介紹。

    7.2 UTF-8:變長的編碼規則

    UTF-8以1個字節為單位,分別使用1個字節、2個字節、3個字節、4個字節對字符進行編碼。

    ( x的序列 --> 代碼點所對應的二進制形式 )

    • 1個字節:對于平面0中的原ASCII字符,使用1個字節進行編碼(兼容ASCII)
      • 0xxxxxxx (填充7位–>128種組合–>128個字符)?
    • 2個字節:對于平面0中的原ASCII字符后面的1920個字符,使用2個字節進行編碼
      • 110xxxxx 10xxxxxx (填充11位–>2048種組合–>2048個字符–>1920 +128=2048)
    • 3個字節:對于平面0剩余的字符,使用3個字節進行編碼
      • 1110xxxx 10xxxxxx 10xxxxxx (填充16位–>65536種組合–>65536個字符–>平面0:65536個字符)
    • 4個字節:對于其它平面(輔助平面)的字符,使用4個字節進行編碼
      • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(填充21位–>?2097151?種組合–>2097151個字符–>遠遠高于字符集實際代碼點最大值)

    7.3 UTF-16:變長的編碼規則

    UTF-16以2個字節為單位,分別使用2個字節、4個字節對字符進行編碼(不兼容ASCII)。

    ( x的序列 --> 代碼點所對應的二進制形式 )

    • 2個字節:對平面0的字符,使用2個字節進行編碼
      • xxxxxxxx xxxxxxxx (16位–>65536種組合–>65536個字符–>平面0:65536個字符)

    ( z的序列 --> 代碼點所對應的二進制數 減去 0x10000 )

    • 4個字節:對其它平面的字符,使用4個字節進行編碼??
      • 110110zz zzzzzzzz 110111zz zzzzzzzz (填充20位–>1048576?種組合–>1048576個字符–>低于字符集實際代碼點最大值–>這也是-0x10000的原因??)

    對于4字節的編碼來說:

    • 高2字節取值范圍:11011000 00000000 - 11011111 11111111 --> D800-DBFF
    • 低2字節取值范圍:11011100 00000000 - 11011111 11111111 --> DC00-DFFF

    現在的問題是:對于2字節的編碼來說,也可能出現110110xx xxxxxxxx 或者 110111xx xxxxxxxx 這樣的編碼。意思就是:2字節的編碼,也可能是以 110110 或者 110111 作為開頭的。這時,我們就無法區分2個字節的數據,它到底是2個字節的編碼還是4個字節編碼的一部分。因為,高位上的 110110 和 110111 是我們進行區分的標識,而2字節編碼的高位也可能是一樣的數值。為了解決這個問題:UNICODE協會禁止 D800 - DFFF 區間的代碼點對應任何字符。這樣的話,2字節的編碼就避免了以 110110 或者 110111 開頭,因為,在這個區間的代碼點沒有對應任何字符。

    7.4 UTF-32:定長的編碼規則

    對每個代碼點都使用固定的4個字節進行編碼(不兼容ASCII),直接將代碼點所對應的二進制擴充為32位(高位補0)即可。

    7.5 Unicode字符存儲的字節序問題

    我們可以常常看到如下形式編碼:UTF-16LE、UTF-16BE、UTF-32LE、UTF -32BE 。為什么UTF-16和UTF-32的后面會有LE、BE的標志呢?為什么UTF-8的后面沒有LE、BE的標志呢?

    UTF-8的存儲過程如下:

    • UNICODE字符集 --> 代碼點 --> UTF-8 --> 編碼值 --> 存儲。

    UTF-16和UTF-32的存儲過程如下:

    • UNICODE字符集 --> 代碼點 --> UTF-16或UTF-32 --> 編碼值 --> 確認排序 --> 存儲。

    為什么需要確認排序?字節順序會影響對數據的解析結果。

    排序是排的哪部分的序?編碼單位內部的字節順序。

    UTF-8字符存儲的字節序問題:
    UTF-8編碼規則,是以字節為單位的。怎么理解呢?字節的存儲順序不影響對數據的解析結果 。所以,它不可能存在亂序的問題。所以,不需要排序。

    比如,對于”小馬奔騰“(下面的編碼都是假設值,并不是真正的值):

    • 小 --> 1字節編碼 0xxxxxxx
    • 馬 --> 2字節編碼 110xxxxx 10xxxxxx
    • 奔 --> 3字節編碼 1110xxxx 10xxxxxx 10xxxxxx
    • 騰 --> 4字節編碼 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

    實際的存儲情況:從第一個字符開始,順序存儲,且每個字符都從高字節開始存儲。存儲內容如下:
    0xxxxxxx 110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    如果我們按照從第一個字符開始,順序存儲,每個字符從低字節開始存儲,仍然不影響解析結果,因為每一個字符的最高字節都有特定的標志。存儲內容如下:
    0xxxxxxx 10xxxxxx 110xxxxx 10xxxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx 11110xxx

    UTF-16字符存儲的字節序問題:
    UTF-16編碼規則,是以2字節為單位的。我們需要知道,2字節的存儲順序不影響對數據的解析結果 ,但是2字節內部的存儲順序則會影響對數據的解析結果。

    比如,對于馬來說:

    • 馬 --> 4字節編碼 110110zz zzzzzzzz 110111zz zzzzzzzz

    是按照110110zz zzzzzzzz 110111zz zzzzzzzz這種格式存儲,還是按照110111zz zzzzzzzz 110110zz zzzzzzzz這種格式存儲,都不影響解析結果,因為對于4字節編碼,每個2字節中的高字節都有特定的開始標志。

    實際的存儲情況:從第一個字符開始,順序存儲,且每個字符都是按照從高2字節開始存儲。

    我們上面也說了,2字節內部的順序可以影響對數據的解析結果。看如下例子:

    假設有如下兩個字的編碼:

    • 奔 --> 4字節編碼 11011010 11011011 11011100 11011101
    • 騰 --> 4字節編碼 11011011 11011010 11011101 11011100

    對于兩字節內部的順序我們可以按照大端的格式存儲,也可以按照小端的格式存儲:

    • BE Big-Endian – 大端:11011010 11011011 11011100 11011101
    • LE Little-Endian – 小端:11011011 11011010 11011101 11011100

    如果解析端未能按照正確的格式解析,就會出現字符解析錯誤的情況。所以,為了避免由于2字節內部的字節順序而導致數據被錯誤的解析,所以,UNICODE給我們提供了LE、BE的選擇。

    那么對于UTF-16兩字節編碼也是同樣的情況:
    假設有如下兩個字符的編碼:

    • 小 --> 2字節編碼 10000000 00000000
    • 馬 --> 2字節編碼 00000000 10000000

    BE:

    • 10000000 00000000

    LE:

    • 00000000 10000000

    UTF-32字符存儲的字節序問題:
    UTF-32編碼規則,是以4字節為單位的,且所有的字符都是固定的4個字節。所以,4字節內部的順序會影響對數據的解析,且存儲只存在兩種情況。

    假設有如下兩個字符的編碼:

    • 小 --> AA AB AC AD
    • 馬 --> BA BB BC BD

    對于不同的字符來說,一定是從第一個字符開始,順序存儲。
    我們有如下兩種情況進行存儲:

    • BE:AA AB AC AD
    • LE:AD AC AB AA

    所以,為了避免由于4字節內部的字節順序而導致數據被錯誤的解析,所以,UNICODE給我們提供了LE、BE的選擇。

    7.6 UTF-16和UTF-32的三種子風格、BOM

    BOM:
    BOM(byte order mark:字節順序標記),放在文本的開頭,用于標識字節序。UTF-16編碼值:U+FE FF 、UTF-32編碼值:U+00 00 FE FF。

    對于不帶BOM的編碼格式,則對于解析端則必須知道編碼格式才能正確解析,否則就會解析錯誤。

    UTF-8帶BOM:
    UTF-8可以帶BOM,但是,這并不會影響字符的存儲的字節順序。它僅僅是用來提示當前文本是使用UTF-8存儲的,僅此而已。

    比如:

    • 我 --> 使用UTF-8不帶BOM的實際存儲效果 --> E6 88 91
    • 我 --> 使用UTF-8帶BOM的實際存儲效果 --> EF BB BF E6 88 91

    UTF-16的三種子風格:
    有如下字符:
    UNICODE字符集 --> 𐃿 --> UTF-16 --> 編碼值:D8 00 DC FF

    實際存儲效果:

    • UTF -16BE --> D8 00 DC FF (windows會存儲為帶BOM的形式,如果其他系統下不會存儲為帶BOM的形式,那么解析的時候必須知道存儲格式才能解析成功,否則解析失敗,將亂碼)
    • UTF -16LE --> 00 D8 FF DC (windows會存儲為帶BOM的形式)
    • UTF-16
      • –> 默認:D8 00 DC FF(實際對應BE)
      • –> 帶BOM:FE FF D8 00 DC FF(實際對應BE)
        –> 帶BOM:FF FE 00 D8 FF DC(實際對應LE)

    UTF-32的三種子風格:
    有如下字符:
    UNICODE字符集 --> 𐃿 --> UTF-32 --> 編碼值:00 01 00 FF

    實際存儲效果:

    • UTF -32BE --> 00 01 00 FF (windows會存儲為帶BOM的形式)
    • UTF -32LE --> FF 00 01 00 (windows會存儲為帶BOM的形式)
    • UTF-32
      • –> 默認:00 01 00 FF(實際對應BE)
      • –> 帶BOM:00 00 FE FF 00 01 00 FF(實際對應BE)
      • –> 帶BOM:FF FE 00 00 FF 00 01 00(實際對應LE)

    注意: 不帶BOM的前提一定是編碼端和解析端已經統一了編碼規則!

    7.7 UCS-2和UCS-4

    關于UCS-2和UCS-4的內容參見如下博客即可:
    細說:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4


    參考資料:

  • 深度學習:C/C++、計算機體系
  • 總結

    以上是生活随笔為你收集整理的字符集:ASCII、GB2312、GBK、GB18030、Unicode的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。