字符集與字符編碼

《字符集與字符編碼》
https://www.yuque.com/saopanda/saopanda/rt7gtg

字符集 是存放字符的集合
字符編碼 是用某個數(shù)字來表示某個字符的規(guī)則,因為計算機上只能存儲二進(jìn)制數(shù)字

ASCII編碼

  • 標(biāo)準(zhǔn) ASCII碼

每個字符占一個字節(jié),使用后 7位,首位固定為0,最多可容納128個字符,共128個字符(ASCII的字符集)

  • 擴展 ASCII碼(高ASCII)

啟用了第8位,補充了附加的128個字符,包括特殊字符、外來語、圖形符號等。

可通過 ASCII碼表,查找 數(shù)字與字符的對應(yīng)關(guān)系
標(biāo)準(zhǔn) ASCII中,最高位(第7位)作為奇偶校驗位。沒懂怎么實現(xiàn)的

GBK編碼

兼容ASCII碼,0~127與ASCII碼一致,不兼容ASCII擴展碼。漢字占用雙字節(jié)

  • GB2312

當(dāng)兩個大于127的字符連接在一起時,才會被識別成一個漢字,容量小 7000多個簡體漢字

  • GBK

大于127的字符出現(xiàn)時,代表漢字開始,與之后一個字符組合識別為一個漢字。由于第二個字符不受限,容量較大,同時兼容GB2312,新增2w多個漢字與字符,包括繁體字

  • GB18030

在GBK的基礎(chǔ)上 增加了一些字符,包括少數(shù)名族字符、特殊字符等

Unicode

統(tǒng)一碼,萬國碼,是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案,它為每種語言每個符號 都設(shè)定了統(tǒng)一且唯一的數(shù)字。Unicode整個編碼系統(tǒng)包含兩部分,編碼方式和實現(xiàn)方式

編碼方式

編碼方式指:Unicode的字符集與數(shù)字的對應(yīng)。既然只是數(shù)字與字符的對應(yīng)關(guān)系,為什么不簡單點直接一一向下排列對應(yīng),還要再弄一個編碼方式 UCS(Universal Character Set)呢?
分組、劃區(qū)、專用區(qū)、代理區(qū)等,便于管理、實現(xiàn)其他功能

Unicode的字符集簡寫為 UCS,早期分為 UCS-2、UCS-4,分別占2字節(jié)和4字節(jié)。
UCS-4 的組成:

  • 首字節(jié),首位固定為 0,7位可用,分為128個 組(group)
    • 第二字節(jié),全部可用,又分為 256個平面(plane)
      • 第三字節(jié),繼續(xù)分為 256行(row)
        • 第四字節(jié),有了 256個碼位(cell)

UCS-4 的 組和平面都為0時,稱作BMP。去掉這倆個0字節(jié),即為 UCS-2

Unicode計劃使用 17個平面,平面0到16,也就是0-0x10FFFF, (2^16) * 17 = 1114112個碼位。

在Unicode5.0中,定義了238605個碼位:
平面15、16有兩個專用區(qū) 655342,平面 0有 6400個碼位的專用區(qū),2048個碼位的代理區(qū)(供 utf-16使用)
所以實際定義的字符有 238605-65534
2-6400-2408=99089個,其中包括 71226個漢字,平面0上27973個漢字,平面2上的43253個都是漢字。

Unicode 兼容 ASCII,從數(shù)字0到127表示的字符與ASCII一致

實現(xiàn):UTF-8編碼

以字節(jié)為單位對Unicode進(jìn)行編碼,不同范圍的字符長度不同

為什么UTF-8編碼下的漢字占 3 個字節(jié)?如下表,漢字的碼點范圍在3字節(jié)長度

字節(jié)長度 格式 實際編碼位 碼點范圍
1 0xxxxxxx 7 0 ~ 127 ASCII
2 110xxxxx 10xxxxxx 11 128 ~ 2047
3 1110xxxx 10xxxxxx 10xxxxxx 16 2048 ~ 65535 漢字所在的范圍
4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 21 65536 ~ 2097151

字節(jié)格式

  • 以 0 開頭表示為單字節(jié)字符
  • 110 表示雙字節(jié)字符開始,1110表示三字節(jié)字符開始,11110表示四字節(jié)字符開始
  • 10開頭表示屬于某個字符的一部分

UTF-8 四字節(jié)編碼,有21位二進(jìn)制可用,Unicode計劃使用的17個面,其最大值0x10FFFF,換算成二進(jìn)制也是21位,所以UTF-8最大表示范圍還比 Unicode大不少

例:“漢” Unicode為 0x6C49,27721,二進(jìn)制 0110 1100 0100 1001,屬于三子節(jié)編碼

尾部對齊替換 “1110xxxx 10xxxxxx 10xxxxxx” 中的 “x”,位數(shù)不足的頭部補 0。替換后,“漢”在UTF-8編碼下的二進(jìn)制表達(dá)如下:

11100110  10110001  10001001

實現(xiàn):UTF-16編碼

UTF-16使用兩個字節(jié)為單位,也就是16個二進(jìn)制位。
當(dāng)碼點小于 0x10000,65536,也就是16位二進(jìn)制足夠表達(dá)時,直接使用碼點原始值。

超出16位的部分如何編碼?

碼點超過 0xFFFF的字符,就把兩個UTF-16單位連接起來,組成一個字符,占4字節(jié)。
其中每個單位的前6位固定,用于標(biāo)識雙單位字符。110110表示該字符的開始,110111表示該字符結(jié)束。

110110xxxxxxxxxx 110111yyyyyyyyyy

然后用該字符的(碼點值 - 0x10000),獲得的新值二進(jìn)制有20位,前10位填入x,后10位填入 y 即可

Unicode最大值 0x10FFFF,UTF-16能放的下嗎?

一個單位的字符有16位,可放 (0xFFFF + 1)個數(shù)
兩個單位的字符有20位(10個x10個y),可放(0xFFFFF + 1)個數(shù),一共可放 0x110000個
剛好也是Unicode可容納的數(shù)量(0x10FFFF + 1)= 0x110000

單單位 與 雙單位 的UTF-16字符如何互不干擾?

第一個標(biāo)識 110110xxxxxxxxxx 范圍是 0xD800-0xDBFF
第二個標(biāo)識 110111yyyyyyyyyy 范圍是 0xDC00-0xDFFF
Unicode將這些范圍設(shè)成了代理區(qū),僅供兩個單位的UTF-16字符使用,所以互不影響

D800-DB7F 高位替代 標(biāo)識第一個單位
DB80-DBFF 高位專用替代 也標(biāo)識第一個單位
DC00-DFFF 低位替代 標(biāo)識第二個單位

高位專用替代是啥?

把該范圍的UTF-16編碼字符反推到 Unicode,其范圍在Unicode的專用區(qū)(平面15、16),所以此代理范圍也被稱作專用替代

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容