字符 字符集 字符編碼 (一)

本文大量借鑒了https://www.cnblogs.com/notbecoder/p/4840783.html里面的內(nèi)容

概述

什么是字符、字符集和字符編碼?
字符指的是文字或者符號(hào)。
字符集指的是字符的集合,一般字符集是一個(gè)完備的字符庫(kù),里面的字符足夠表意。
人與人之間用于交流的文字符號(hào),計(jì)算機(jī)并不能理解,也不能處理。為了讓人與計(jì)算機(jī)、計(jì)算機(jī)與計(jì)算機(jī)之間可以正常交流,人發(fā)明了各種計(jì)算機(jī)字符集、字符編碼。
字符集只是字符的集合,里面的每個(gè)字符都會(huì)對(duì)應(yīng)一個(gè)字符代碼,如ASCII碼中"a"對(duì)應(yīng)數(shù)字97。但是字符代碼不一定適合作網(wǎng)絡(luò)傳送、處理,有時(shí)字符須經(jīng)過(guò)編碼(encode)后才能應(yīng)用,這就是字符編碼。我們常用的ASCII碼、GBK、GB2312等字符集,除了具有字符集層面的含義之外,還具有字符編碼的意思(也就是字符代碼和字符編碼是一樣的)。但我們常用的Unicode字符集(兩個(gè)字節(jié)),根據(jù)不同的使用需要,會(huì)將字符重新編碼,比如UTF8(不定長(zhǎng),1 ~ 8字節(jié))、UTF16(不定長(zhǎng),2 ~ 4字節(jié))、UTF32(定長(zhǎng),4字節(jié))都是Unicode字符集的編碼實(shí)現(xiàn)。

計(jì)算機(jī)中的字符集和字符編碼

因?yàn)橛?jì)算機(jī)只能理解二進(jìn)制,計(jì)算機(jī)中,是使用二進(jìn)制字節(jié)的方式表示字符。在計(jì)算機(jī)中建立一種編碼模型需要下面四步:

1、要有一個(gè)字符庫(kù),確定這些字符足夠表意。 比如ASCII字符集,已經(jīng)足夠表示英語(yǔ),但不能表示中文,于是產(chǎn)生GB2312字符集。所以市面上有很多字符集,經(jīng)常會(huì)出現(xiàn)亂碼問(wèn)題
2、第一層編碼,給每個(gè)字符編個(gè)數(shù)字,英文叫Code Point 或 Code Position。比如ASCII字符集中,65表示“A”,97表示“a”。
3、第二層編碼,確定表示字符的二進(jìn)制位數(shù)(8位,16位,32位)。ASCII使用7位(01000001表示“A”),DBCS(雙字節(jié)字符集)使用16位。
4、第三層編碼,確定字符二進(jìn)制值的存儲(chǔ)格式(大端法,小端法)

常見(jiàn)的字符集和字符編碼

ASCII編碼

我們經(jīng)常說(shuō)ASCII時(shí),包含了字符集和字符編碼兩種意思。ASCII碼是英文字符集,使用一個(gè)字節(jié)編碼一個(gè)字符(一開(kāi)始的ASCII用7 bits表示一個(gè)字節(jié),第8位空余),這套字符編碼,已經(jīng)可以完全涵蓋英文字符。不過(guò)對(duì)于日文、韓文和漢字來(lái)說(shuō),是完全不夠用的。所以很多國(guó)家發(fā)明了自己的字符集和字符編碼,但一般都兼容了ASCII碼。

ISO-8859編碼

由于各公司、國(guó)家之間都有自己的字符集,同一個(gè)數(shù)值,在不同的字符集之間表示的符號(hào)可能不一樣,這樣在一臺(tái)電腦上正??梢蚤喿x的文件,到另外一臺(tái)電腦可能就成了亂碼。為了解決這個(gè)問(wèn)題,ISO組織統(tǒng)一了一套標(biāo)準(zhǔn)字符集,就是ISO-8859.不過(guò) ISO-8859 不是一個(gè)字符集,而是一系列擴(kuò)充的ASCII碼字符集。ISO-8859也是單字節(jié)字符集,用一個(gè)字節(jié)表示一個(gè)字符。

 ISO/IEC 8859-1 (Latin-1) - 西歐語(yǔ)言
  ISO/IEC 8859-2 (Latin-2) - 中歐語(yǔ)言
  ISO/IEC 8859-3 (Latin-3) - 南歐語(yǔ)言。世界語(yǔ)也可用此字符集顯示。
  ISO/IEC 8859-4 (Latin-4) - 北歐語(yǔ)言
  ISO/IEC 8859-5 (Cyrillic) - 斯拉夫語(yǔ)言
  ISO/IEC 8859-6 (Arabic) - 阿拉伯語(yǔ)
  ISO/IEC 8859-7 (Greek) - 希臘語(yǔ)
  ISO/IEC 8859-8 (Hebrew) - 希伯來(lái)語(yǔ)(視覺(jué)順序)
  ISO 8859-8-I - 希伯來(lái)語(yǔ)(邏輯順序)
  ISO/IEC 8859-9(Latin-5 或 Turkish)- 它把Latin-1的冰島語(yǔ)字母換走,加入土耳其語(yǔ)字母。
  ISO/IEC 8859-10(Latin-6 或 Nordic)- 北日耳曼語(yǔ)支,用來(lái)代替Latin-4。
  ISO/IEC 8859-11 (Thai) - 泰語(yǔ),從泰國(guó)的 TIS620 標(biāo)準(zhǔn)字集演化而來(lái)。
  ISO/IEC 8859-13(Latin-7 或 Baltic Rim)- 波羅的語(yǔ)族
  ISO/IEC 8859-14(Latin-8 或 Celtic)- 凱爾特語(yǔ)族
  ISO/IEC 8859-15 (Latin-9) - 西歐語(yǔ)言,加入Latin-1欠缺的芬蘭語(yǔ)字母和大寫(xiě)法語(yǔ)重音字母,以及歐元(€)符號(hào)。
  ISO/IEC 8859-16 (Latin-10) - 東南歐語(yǔ)言。主要供羅馬尼亞語(yǔ)使用,并加入歐元符號(hào)。
GBK編碼

GBK字符集是漢字字符集,每?jī)蓚€(gè)字節(jié)表示一個(gè)字符,兼容了ASCII碼,屬于定長(zhǎng)編碼。

Unicode字符集

上面介紹的字符集都屬于本地字符集,在一國(guó)之內(nèi)使用沒(méi)問(wèn)題,跨國(guó)就不行了。如果一個(gè)計(jì)算機(jī)只能識(shí)別ACSII碼集,要展示漢字就亂碼了。而且每個(gè)國(guó)家都使用自己的字符集的話,會(huì)經(jīng)常遇到亂碼問(wèn)題,不利于信息的傳輸和知識(shí)的傳播,對(duì)電腦和互聯(lián)網(wǎng)的普及都會(huì)帶來(lái)一定的阻礙。
所以Unicode字符集被發(fā)明了,Unicode又稱為萬(wàn)國(guó)碼,可以表示世界上各個(gè)國(guó)家的字符。但是Unicode只是定義了每個(gè)字符用什么數(shù)字表示,屬于計(jì)算機(jī)編碼模型中的第一層編碼,在實(shí)際的存儲(chǔ)和傳輸過(guò)程中,我們并不使用Unicode作為字符的編碼,而一般是采用UTF-8編碼,Unicode的一種實(shí)現(xiàn)方式。

UTF-8編碼

UTF-8與Unicode有什么關(guān)系呢?
UTF,全稱“Unicode Transformation Formats”。是Unicode的編碼格式。UTF-8是變長(zhǎng)編碼,以一個(gè)字節(jié)為單位對(duì)Unicode字符進(jìn)行編碼。英文等ASCII碼表中出現(xiàn)的字符用UTF-8表示的時(shí)候,仍然只會(huì)使用一個(gè)字節(jié),所以在傳輸英文的時(shí)候,使用UTF-8會(huì)節(jié)省很多空間。

我們看看Unicode編碼是如何轉(zhuǎn)化為UTF-8編碼的:

Unicode編碼(十六進(jìn)制) UTF-8 字節(jié)流(二進(jìn)制)
00000000 - 0000007F 0xxxxxxx
00000080 - 000007FF 110xxxxx 10xxxxxx
00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

“中國(guó)”兩個(gè)漢字的Unicode編碼為:4E2D 和 56FD。
“中國(guó)”兩個(gè)漢字的UTF-8編碼為:E4B8AD 和 E59BBD。
以“中”為例,UTF-8編碼轉(zhuǎn)化為二進(jìn)制是:
1110 0100
10 111000
10 101101
去掉每個(gè)字節(jié)的頭部,剩下的二進(jìn)制串為 0100 1110 0010 1101,轉(zhuǎn)化為16進(jìn)制為4E 2D,正好是“中”的Unicode編碼。

Unicode字符有幾個(gè)字節(jié)

經(jīng)常會(huì)困惑一個(gè)問(wèn)題,Unicode字符占用幾個(gè)字節(jié)?
Unicode字符一開(kāi)始被發(fā)明的時(shí)候,只有兩個(gè)字節(jié)(也就是UCS-2),但是到后面發(fā)現(xiàn)有一些漢字(比較冷僻的),Unicode的碼點(diǎn)已經(jīng)用完,無(wú)法表示了。后面ISO對(duì)Unicode編碼進(jìn)行了擴(kuò)展(也就是UCS-4),用四個(gè)字節(jié)表示一個(gè)字符,這樣就完全夠用了。

  • UTF-8屬于變長(zhǎng)編碼,最大長(zhǎng)度是6個(gè)字節(jié), UTF-8的4個(gè)字節(jié),可以表示0x10000-0x001FFFFF的Unicode(最多21位)。
    4個(gè)字節(jié)以內(nèi),已經(jīng)包含了Unicode所有字符。
    5、6個(gè)字節(jié)表示的已經(jīng)是非Unicode編碼范圍,屬于UCS-4 編碼。早期UTF-8規(guī)范也可以達(dá)到6字節(jié)序列,不過(guò)2003年11月UTF-8 被 RFC 3629 重新規(guī)范,只能使用原來(lái)Unicode定義的區(qū)域, U+0000到U+10FFFF。根據(jù)規(guī)范,這些字節(jié)值將無(wú)法出現(xiàn)在合法 UTF-8序列中。
  • UTF-16屬于變長(zhǎng)編碼,UTF-16是完全對(duì)應(yīng)于UCS-2的,但是它通過(guò)一種代理機(jī)制(感興趣可以自己去看看),用兩個(gè)UTF-16碼元也可以表示UCS-4字符集里面的字符。
  • UTF-32屬于定長(zhǎng)編碼,UTF-32是完全對(duì)應(yīng)于UCS-4的
    所以,Unicode到底用幾個(gè)字節(jié)表示,取決于我們使用了它的哪種實(shí)現(xiàn)方式是(在選擇文件的編碼時(shí),沒(méi)有Unicode這個(gè)選項(xiàng)),是UTF-8,UTF-16,還是UTF-32。我們文件采用的編碼方式是UTF-32,則Unicode是4個(gè)字節(jié)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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