❶ 計算機中英文字元使用是什麼編碼,漢字又是使用什麼編碼,還有哪些編碼
那編碼可多了。
一般純英文單位元組字元都用ascii碼戚局。
漢字是雙位元組字元,常見的編碼嫌仔茄有gb2312,gbk,utf8.
另外還芹察有ISO組織推出的unicode
❷ 計算機中應用最普遍的字元編碼是
計算機帶埋中應用最普遍的字元編碼是ASCII碼。
ASCII碼使用指定的7位或8位二進制數組合來表示128或256種可能的字元。標准ASCII碼也叫基礎ASCII碼,使用7位二進制數(剩下的1位二進制為0)來表示所有的大寫和小寫字母,數字0到9、標點符號,以及在美式英語中使用的特殊控制字元。
字元編碼也稱字集碼,是把字元集中的字元編碼為指定集合中某一對象(例如:比特模式、自然局閉數序列、8位組或者電脈沖),以便文本在計算機中存儲和通過通信網路的傳遞。常見的例子包括將拉丁字母表編碼成摩斯電碼和ASCII。
常見的編碼方式
GB2312對ANSI編碼最初始的ASCII編碼進行擴充,為了滿足國內在計算機中使用漢字的需要,中國國家標准總局發布了一系列的漢字字元集國家標准編碼,統稱為GB碼,或國標碼。
BIG5又稱大五碼或五大碼,1984年由台灣財團法人信息工業策進會和五間軟體公司宏碁 (Acer)、神通(MiTAC)、佳佳、零壹(ZeroOne)、大眾(FIC)創蠢臘螞立,故稱大五碼。
❸ 計算機常用的信息編碼有哪幾種
計算機常用的編碼有:ASCII碼,漢字編碼等
❹ 計算機有哪些編碼方式
指電腦內部代表字母蠢型返或數字的方式,常帶飢見的編碼方式有:ASCII編碼、GB2312編碼(簡體中文)、GBK、BIG5編碼(繁體中租襲文)、ANSI編碼、Unicode、UTF-8編碼等。
❺ 字元編碼簡述
眾所周知,java中如果要計算一個字元串的長度,可以直接利用String的length方法。如下:
顯然,這里的length方法計算的字元數,一個英文字母按一個字元計算,一租高此個中文漢字也是按照一個字元進行計算的。
不過,如果想要獲取字元串的位元組數呢?String依然提供了現成的方法供我們使用,如下所示:
這里,可以看到幾個注意點:
先來看第一點,也是本文主要想討論的問題:UTF-8、GBK的區別是什麼,為什麼會導致最終獲取的位元組數不一樣?
要解答上面的問題,需要先知道GBK和UTF-8分別是什麼。
簡單的說,GBK和UTF-8是兩種字元的編碼方式。那麼,問題又來了,什麼是字元的編碼方式呢?除了GBK和UTF-8,有沒有其他的編碼方式呢?其中的區別又在哪裡?
關於字元的編碼方式,姑且可以念逗簡單的理解為,將一個字元表示成一串bit流的規則(這個說法是不太准確的,下文會有詳細解弊迅釋)。比如說,UTF-8就是一種非常常用的字元編碼方式,「漢」字以UTF-8的規則計算後表示出來的bit流就是「11100110 10110001 10001001」。
有些時候,編碼方式,還會被稱為編碼規則、編碼方案。
實際上,從計算機不再單純地拿來進行數字計算開始,字元的編碼方式就一直在不斷的演進,現在就借著這一段歷史,來對包括GBK、UTF-8在內的幾種常見字元編碼方式進行下介紹。
計算機剛出世的時候,美國人為了交流通信方便,約定了一套字元編碼方式,就是ASCII碼。
ASCII全稱為American Standard Code for Information Interchange,即美國信息互換標准碼。
ASCII碼的字元集中包含了26個英文字母、10個數字(0-9)、一些常見的符號(@、#、!),基本能夠滿足在英語環境下的需求。ASCII字元集裡面只有128個字元,每個字元都有一個編號,也就是0-127。而當時大家已經習慣於用8個bit來表示一個位元組,所以乾脆取一個位元組來表示一個字元。其中,最高位置為0,其他位全部用上,總共128個位置,剛好能夠與ASCII字元集一一對應。
舉個例子,在ASCII碼中,『A』對應的編號是65,用一個位元組表示就是「01000001」。
這里對引入的兩個新概念做下解釋:
字元集 :字面上理解就是字元的集合。
編號字元集 :指帶有數字編號的字元集合,有時候也簡稱為字元集。例如:[1:a, 2:b, 3:c],在此字元集中,包含三個字元:a、b、c,並且其編號分別為1,2,3。
不過,後來計算機傳到了歐洲,不少歐洲國家的語言使用ASCII碼無法完整地進行表示,比如德語、法語。上文可以看到,在ASCII編碼中,一個ASCII字元,是用一個位元組來表示的。一個位元組實際上能夠表示256個數字,也就至少能夠表示256個字元,而ASCII字元集只有128個字元。所以這時候出現了多種基於ASCII的編碼方式。大家的基本思路都是一樣的:還是使用一個位元組表示一個字元,0-127依然用來表示ASCII字元集(字元編號與ASCII碼保持一致),128-255拿來表示自己語言中的特殊字元。
顯然,這么搞出來的多個編碼方式互不兼容,大家會很痛苦。所以最後出現了兩套統一的編碼方案,能夠對歐洲各國的字元都進行支持。這兩套編碼方案分別是:EASCII(Extended ASCII)字元編碼方案,ISO/IEC 8859字元編碼方案。
這兩套方案也是沿用上面的思路:0-127依然用來表示ASCII字元集(字元編號與ASCII碼保持一致),128-255用來表示歐洲各國的特殊字元(這部分字元集又被稱為擴展字元集)。
由於在這兩種編碼方案中,ASCII字元集中的字元,保留了與ASCII碼相同的字元編號,所以 這兩種編碼方案都是對ASCII編碼完美兼容的 。
不過,與ASCII、EASCII屬於單個獨立字元集不同,ISO/IEC 8859是一組字元集的統稱。其下共有15個字元集,即ISO/IEC 8859-n,n=1,2,3 …… 15,16(其中12未定義,所以共15個)。
到現在為止,EASCII已經很少有人用了,ISO/IEC 8859卻是被廣泛使用,其中ISO/IEC 8859-1被使用的最為普遍。而ISO/IEC 8859-1又被簡稱為ISO 8859-1,而且它還有一個Latin-1(也寫作Latin1)的簡稱。
終於,計算機來到了中國。如上文所述,仿照ASCII碼的規則,1個位元組最多也就只能表示256個字元。但是,中國漢字有幾萬個,常用字就有幾千個,這樣的話,1個位元組是完全不夠用的。所以,當時的全國信息技術標准化技術委員會搞了一套自己的編碼方案:用兩個位元組表示一個字元。這就是GB系列編碼。「GB」是「國標」的拼音首字母縮寫,意為「國家標准」。
最早的GB編碼就是GB2312,收錄了6763個漢字和682個符號,基本能夠滿足日常需求。
GB2312規定,一個漢字的編號必須大於127,並且編號大於127的字元必須用兩個位元組來表示。而0-127,仍然用來表示之前的ASCII字元集,這部分字元的編號依舊與ASCII碼保持一致,並且只有一個位元組來表示。
所以,GB2312對ASCII碼是完全兼容的。不過GB2312對ISO是不兼容的,因為它舍棄了ISO中128-255之間的字元映射。
同時,也可以認為,在GB2312中,英文字元只佔一個位元組,而中文字元會占兩個位元組。
而計算機在依照GB2312編碼進行字元識別時,會先判斷第一個位元組的第一個bit位是否為0,如果是,則讀取1個位元組,進行編碼解析;如果不是,則讀取兩個位元組,進行編碼解析。
此外,當時出於種種原因考慮,GB2312對ASCII碼中的西文字母、數字、標點等特殊符號進行了重新編碼,用兩個位元組來進行表示。所以,這類字元在GB2312中就有了兩種編碼表示,其中小於128的編碼(用1個位元組表示),就被稱為半形字元,大於128的編碼(用2個位元組表示),就被稱為全形字元。
到目前為止,由於當時導致全形字元出現的歷史原因已經不再存在,所以只有很少的一些全形字元還在使用(比如中文的逗號,問號,感嘆號,空格等),其他的許多全形字元已經很少用了。
雖然GB2312能夠滿足基本的日常需求,但是畢竟收錄的漢字還是太少,繁體字、生僻字是不包含在GB2312字元集中的。由此,有關部門對GB2312進行了擴展,推出了GBK編碼。
GBK與GB2312基本一致,都是使用兩個位元組來表示漢字。不過有一點不一樣:在GB2312中,表示漢字的兩個位元組中,其首位必須都是1;而在GBK中,只要求第一個位元組(高位元組)的首位為1,對於第二個位元組(低位元組),沒做要求。當然,如果首位為0,都是用來表示ASCII字元集里的內容。
GBK可以認為是對GB2312的擴展,其對GB2312是完美兼容的。所以,GBK對ASCII碼也是完美兼容的。
GB18030是對GBK的進一步擴展,在擴展現有漢字的基礎上,收錄了數千個少數民族的字元。其由中國國家質量技術監督局於2000年3月17日推出,用以取代GBK。
GB18030同樣保持向下兼容,其對GBK、GB2312、ASCII編碼完美兼容。
諸如GB2312、GBK、GB18030之類的編碼格式,被程序員們稱為DBCS(Double Byte Charecter Set:雙位元組字元集)。在DBCS的標准里,英文字元用一個位元組表示,並且這個位元組的第一位必然為0(英文字元對應的字型大小小於128);中文字元用兩個位元組表示,第一個位元組的第一位必然為1。
如上文所述,在計算機的傳播途中,為了兼容各地的語言,出現了許許多多的編碼方案。但是遺憾的是,這些編碼方案互不兼容,直接影響到了信息的傳播,這也催生了能夠兼容全球各種字元的統一編碼方案的出現。
歷史上存在兩個獨立的嘗試創立單一字元集的組織:
不過在1991年前後,兩個項目組發現沒必要存在兩個不兼容的字元集,所以它們開始合並雙方成果,約定使用統一的編碼表。從Unicode 2.0開始,Unicode項目採用了與ISO 10646-1相同的字型檔與字碼,ISO也承諾,ISO將不會替超出U+10FFFF的UCS-4編碼賦值,以使得兩者保持一致(UCS的概念下文會有詳述,此處不必過於關注)。
目前,這兩個項目組仍獨立存在,並獨立地發布各自的標准,不過二者約定保持雙方的標准碼表兼容,並共同調整任何未來的擴展。
ISO 10646標准,只是一個簡單的字元集表。它定義了一些編碼的別名,指定了一些與標准有關的術語,並包括了規范說明,指定了怎樣使用UCS鏈接其他ISO標準的實現,比如ISO/IEC 6429和ISO/IEC 2022。還有一些與ISO緊密相關的,比如ISO/IEC 14651是關於UCS字元串排序的。
Unicode標准,額外定義了許多與字元有關的語義符號學內容,並詳細說明了繪制某些語言(如阿拉伯語)表達形式的演算法、處理雙向文字(比如拉丁文和希伯來文的混合文字)的演算法、排序與字元串比較所需的演算法等。
在書寫Unicode編碼時,規定以十六進制數來進行表示,並需要加上「U+」前綴。比如「漢」字的Unicode編碼為「U+6C49」。
為了能夠更方便地介紹後續的內容,這里需要先解釋清楚幾個名詞(個人認為這幾個概念有助於理解後續的內容,如果不想看,可以直接跳過此節)。
編號字元集(CCS:Coded Character Set) :指帶有數字編號的字元集合。上文已經介紹過了。
字元編碼方式(CEF:Character Encoding Form) :將字元集的數字編號轉換為位元組流的規則。
還是上文中的例子,Unicode字元集中的「漢」字,在Unicode字元集中的編號是0x6C49,在UTF-8編碼中,需要使用3個位元組來表示,表示成二進制則是「11100110 10110001 10001001」(UTF-8的具體編碼規則,下文會有詳述)。
在這個例子中,Unicode就是所謂的編號字元集(CCS),UTF-8編碼便是字元編碼方式(CEF)。
實際上,在unicode字元集出世之前,字元集與編碼方式往往是耦合在一起的,一套字元集往往也只有一套編碼規則,這兩個概念也沒必要嚴格區分,人們也經常進行混用。比如ASCII碼既可以認為是一套字元集,也可以認為是一種字元編碼方式。
但是,Unicode字元集出現之後,字元集和編碼方式被分離解耦了。此時,一套字元集可能有多套的編碼規則,我們所熟知的UTF-8、UTF-16就是建立在Unicode字元集上的字元編碼方式。
編碼規則大致上可以分為兩類:直接映射與間接映射。
直接映射 ,是指字元在字元集中的數字編號與編碼後的編碼串是一樣的。比如ASCII字元集中,『A』對應的字元編號是65,換算成二進制為「1000001」,按照ASCII碼編碼後,用一個位元組來表示,就是「01000001」,也就是十進制中的65。編碼前後,其實可以視為是一樣的。
間接映射 ,就是字元在字元集中的數字編號與編碼後的編碼串不一定一樣。還是上面的例子,unicode字元集中「漢」字的字元編號為0x6C49,如果換算成二進制就是「01101100 01001001」,但是UTF-8編碼後要用三個位元組來表示,表示成二進制就是「11100110 10110001 10001001」。編碼前後,數值不一樣。
其實,Unicode出現之前,大家一直用的都是直接映射,編碼前後數值是一樣的,這也是一直沒有明確區分字元集和編碼方式這兩個概念的一個原因。
解釋清楚了這幾個概念,下面我們繼續:
UCS全稱為「Unicode Character Set」,是由ISO制定的ISO 10646標准所定義的標准字元集。
UCS又稱「Universal Multiple-Octet Coded Character Set」,譯為通用多八位編碼字元集。
相對應的,Unicode項目所使用的標准字元集通常被稱為Unicode字元集。
如上文所述,Unicode 2.0發布時,Unicode字元集與UCS字元集基本保持了一致,之後雖然二者獨立存在,但是一直在保持互相的兼容。
在ISO與unicode合並之前,ISO就有一套字元編碼模式,也就是UCS-2。
UCS-2的規則就是用兩個位元組來表示字元集中的字元,並且它使用的是直接映射的方式。所以可以簡單理解為,UCS-2就是將字元的數字編號直接轉化為二進制,然後用兩個位元組來進行存儲。
與ASCII類似,此時的UCS-2其實可以視為一套字元集,也可以視為一套編碼規則。
UCS-2用兩個位元組來表示一個字元,所能容納的字元數量為2^16 = 65536個。
在ISO與Unicode合並字元集之後,雙方約定字元集需要容納的字元數量遠遠超過65535個(到目前為止,Unicode字元集可容納的字元量為2^16 * 17 = 1114112個),此時UCS-2顯然不夠用了,所以ISO推出了新的規則,就是UCS-4.
UCS-4與UCS-2基本一樣,唯一的不同點是,UCS-4使用4個位元組來表示一個字元。
同樣,UCS-4可以認為是一套字元集,也可以認為是一套編碼規則。
在有些文章里,UCS-4有廣義和狹義兩種含義,廣義上UCS-4包含UCS-2,狹義上不包含。個人理解,在指代字元集的時候,UCS-4包含UCS-2,但是在指代編碼規則時,UCS-4不包含UCS-2。
UCS-2全稱2-byte Universal Character Set,直譯為2位元組通用字元集。
UCS-4全稱4-byte Universal Character Set,直譯為4位元組通用字元集。
注意:UCS-2和UCS-4組成的UCS字元集,都可以採用UTF-8、UTF-16、UTF-32進行編碼。所以UCS-2與UTF-16並不等同,UCS-4與UTF-32也不等同。
如上文所述,ISO與Unicode合並之後,ISO推出了UCS-4。但是Unicode推出的卻是另外一套編碼規則:UTF-16.
UTF-16源於UCS-2,但是與UCS-2不太一樣。UCS-2屬於定長編碼方式,永遠使用兩個位元組來表示一個字元。而UTF-16屬於變長編碼方式,對於UCS-2字元集中的字元(0x0000~0xFFFF)使用2個位元組來表示,對於UCS-4字元集中除開UCS-2里的字元(0x10000~0x10FFFFF),使用4個位元組來表示。
UTF-16的編碼規則屬於間接映射。對於UCS-2字元集裡面的內容,保持字元編號與生成的編碼串相同,但是對於UCS-4中的其他字元(指除開UCS-2中的字元),字元編號與最終的編碼串並不相同。這里採取了一套計算演算法:代理機制。不過本文對此不做深究。
雖然UTF-16能夠滿足需求,但是一來對於ASCII字元集中的字元,UTF-16仍然需要使用兩個位元組來存儲(這樣會有一個位元組的空間被浪費),並且ASCII中的字元,其UTF-16編碼的第一個位元組將永遠是0x00,而C語言中又因為會將此位元組視為字元串末尾導致字元串無法正常解析。所以UTF-16剛推出的時候,就受到了很多的抵制。
由此,UTF-8出現了。
UTF-8也是一種變長編碼方式,它使用1到4個位元組來表示一個字元。
字元編號為0~127(十進制)的字元,使用一個位元組進行表示。
字元編號為128~2047(十進制)的字元,使用兩個位元組進行表示。
字元編號為2048~65535(十進制)的字元,使用三個位元組進行表示。
字元編號為65536~2097151(十進制)的字元,使用四個位元組進行表示。
UTF-8和UTF-16,都屬於間接映射。也就是說,字元編號與最終的編碼並不完全是一樣的。
實際上,UTF-8的編碼規則如下:
還是上文中的例子,Unicode字元集中的「漢」字,字元編號以16進製表示為「0x6C49」,換算成十進制就是27721,所以需要使用三個位元組進行表示。而「0x6C49」換算成二進制就是「110110001001001」,代入上圖中三位元組的編碼規則(「1110xxx 10xxxxxx 10xxxxxx」),最終得到的就是"1110110 10110001 10001001"。
當然,對於ASCII字元集裡面的字元(字元編號小於128),UTF-8隻需要一個位元組即可表示。與UTF-16的兩個位元組相比,空間利用率更高(同樣,在進行數據傳輸時,效率也更高)。
也因此,UTF-8對於ASCII碼屬於完美兼容,而UTF-16隻能算是間接兼容(畢竟多了一個位元組,解析的時候還需要進行轉化)。考慮到計算機世界裡ASCII字元的廣泛性,這一點意義重大。
順便說一句,雖然上面並沒有介紹UTF-16的代理機制,但是可以說明的是,這個代理機制的演算法要比UTF-8的演算法更加復雜,一定程度上也導致了UTF-16進行編碼和解碼需要耗費更多的資源。
此外,可以看到,UTF-8編碼產出的位元組,都帶有固定的前綴。這樣做有幾個好處:
第一,字元使用UTF-8編碼之後,第一個位元組的前面的幾位,可以明確標識出來,此字元需要幾個位元組才能表示出來。這樣的話,解碼程序在讀入每一個位元組的時候,就能夠知道當前位元組是否為一個字元的首位元組;如果是首位元組的話,立刻就能知道還需要讀入幾個位元組才能解析出來這個字元。
第二,字元經UTF-8編碼之後,生成做到多個位元組中,第一個位元組的固定前綴與後續位元組的固定前綴都不一樣。這樣就保證,在傳輸過程中,如果出現了局部的位元組錯誤,比如增加、丟失、修改了某些位元組。將只會影響到有限個字元,並不會導致後續的所有的字元都解析錯誤。這一點是UTF-16、UTF-32、GB系列都做不到的事情。
第三,同樣因為編碼後,首位元組的前綴與後續位元組的前綴都不同,所以從UTF-8位元組流中的任一位元組開始,往後或者往前都可以很輕易的找到當前字元或者臨近字元的起始位置。
第四,依照目前的規則(檢查首位元組,在第一個0出現之前,有幾個1,就代表當前字元需要用多少個位元組進行表示),UTF-8可以很輕易地擴展到5個位元組、6個位元組,甚至是7個位元組和8個位元組。這就保證了UTF-8可以很輕易地支持Unicode字元集的不斷擴充。
與UTF-8和UTF-16相比,UTF-32就比較簡單了。
UTF-32的編碼規則屬於直接映射,並且每個字元都使用四個位元組來表示。
因此,UTF-32比UTF-16更浪費空間。但是因為使用的是定長編碼(每個字元都是四個位元組),所以文本處理速度上要比UTF-8和UTF-16快一些。
在三大UTF編碼中,UTF-32既不是最早出現的(UTF-16),也不是最優設計(目前公認UTF-8為最優設計),所以目前已經很少有地方在用了。
上文聊到一個內容,UTF-16編碼,有可能使用兩個或者四個位元組來表示一個字元。那麼問題來了,假設存在一個字元,其用UTF-16編碼之後,對應的位元組流,用16進製表示為0xFA 0xFB。這時候,在計算機存儲與傳輸中,到底應該是0xFA放前面呢,還是應該0xFB放前面呢?
比較遺憾的是,在計算機發展歷程中,出於各種各樣的原因,大家並沒有形成統一,而是出現了多種方案,比較常見的是如下兩種:
一、大端序(Big-Endian):又稱高尾端序,即數據的尾端存儲在內存的高地址;數據的頭端存儲在內存的低地址。
二、小端序(Little-Endian):又稱低尾端序,即數據的尾端存儲在內存的低地址;數據的頭端存儲在內存的高地址。
為了方便理解記憶,這里用幾個例子來對大端序和小端序進行下簡單的說明。
首先,我們在閱讀和書寫二進制串時,總是高位在前,低位在後。比如,拿「漢字」為例,其中「漢」對應的unicode編碼為「U+6C49」,「字」對應的unicode編碼為「U+5B57」,如下所示:
而計算機內存的地址增長,我們設定為從左到右,如下圖所示:
那麼這種情況下,大端序,就是將寫入內存時,位元組順序不變。如下所示:
而小端序,就需要將位元組串前後顛倒一下順序,再寫入內存,如下所示:
注意:
不過,問題來了,上面舉的例子中,「漢」和「字」在UTF-16編碼下,都只需要兩個位元組就能表示。那對於需要四個位元組才能表示的字元呢?這里選取兩個字元,對應的unicode編碼分別為"U+129024"( http://www.52unicode.com/leftwards-arrow-with-small-triangle-arrowhead-unicode )與「U+4E00」( http://www.52unicode.com/ideograph-one-a-an-alone-cjk-unicode )。其中第一個字元使用UTF-16進行編碼時需要做間接映射,需要用4個位元組來表示,而第二個位元組做直接映射即可。如下:
此時,在兩種位元組順序中的表現如下:
大端序:
小端序:
可以看到,在UTF-16中,即使對於需要使用四個位元組來表示的字元,大端序和小端序的作用范圍還是被限制到了兩個位元組。
實際上,這里有一個碼元(code unit)的概念。
在解釋碼元之前,需要先解釋另外一個概念:CES。
CES,全稱Character Encoding Scheme,可以直譯為字元編碼模式,是指將位元組流轉換為最終的bit流的規則。
而上文中,提到過兩個相關的概念:CCS(編號字元集)和CEF(字元編碼方式)。
CCS(Coded Character Set):編號字元集,指帶有數字編號的字元集合。
CEF(Character Encoding Form):字元編碼方式,將字元集的數字編號轉換為位元組流的規則。
三者之間的關系如下:
舉個例子(為了方便閱讀,最終的bit流以16進制的方式展示):
其中,CEF得出的位元組流可以理解為數字編號在計算機中邏輯表示方式,我們前面介紹到的UTF-8、UTF-16都是CEF;而CES的得出bit流序列可以理解為數字編號在計算機中的物理表現方式,上面提到的位元組序(大端序、小端序等),就可以認為是字元編碼中的CES。
回到碼元的概念。碼元,可以認為是CEF在將位元組流轉變為bit流時的最小操作單元。
舉個例子,UTF-16中,以2個位元組為一個碼元,所以在生成bit流時,只會在2個位元組內執行大端序和小端序的排序規則。
類似的,在UTF-32中,以4個位元組為一個碼元。但是,在UTF-8中,以1個位元組作為一個碼元,所以在使用UTF-8進行編碼時,大端序和小端序其實並不會起作用。
由於在使用諸如UTF-16或者UTF-32等以多個位元組作為一個碼元的編碼方式時,對於同一個bit串,使用大端序和小端序解析出來的最終結果很有可能完全不同。所以,在進行數據傳輸時,數據的生產方必須告知接收方應該使用哪種方式進行解析。而這個告知操作便由BOM(Byte-Order Mark)來實現。
在Unicode中,有一個字元,其編碼為U+FEFF,其含義為零寬度不中斷空格(ZERO WIDTH NO-BREAK SPACE)。它名義上是個空格,但是寬度為0,所以不可見,也無法被列印出來,換句話說,這個字元其實沒啥用。
但是BOM便是藉助於這個字元來實現。
為了告知位元組流的接收方,這串bit的位元組順序是什麼樣子的,約定了個辦法。就是在每串位元組流前面,都要添加一個上述的字元U+FEFF。對於UTF-16如果是大端序,首先讀出來的兩個位元組就會是0xFE 0xFF;如果是小端序,首先讀出來的兩個位元組就會是0xFF 0xFE。這個強行載入位元組流最前面,用來表示位元組序的字元,就是上文所說的BOM。類似的,對於UTF-32,如果是大端序,首先讀出來的就是0x00 0x00 0xFE 0xFF,而如果是小端序,首先讀出來的就是0xFF 0xFE 0x00 0x00.
從Unicode 3.2開始,U+FEFF這個字元被規定只能出現在位元組流的開頭,且只能用於標識位元組序,所以這個字元又有了個別名:位元組序標記。不過Unicode又添加了個字元用於標識零寬度不中斷空格,編碼為U+2060。
上文也提到過,對於UTF-8來說,不存在位元組序所帶來的問題,所以,UTF-8產出的位元組流是根本不需要BOM的。不過某些時候,還是會給UTF-8的位元組流添加一個BOM注意此時並不是為了標識當前的位元組序,而是表示當前位元組流是用UTF-8編碼完成的(畢竟UTF-8根本沒有位元組序問題需要BOM解決)。而在UTF-8前面添加的這個BOM,對應的位元組流是0xEF 0xBB 0xBF。
對BOM做下簡單的整理,如下:
現在,回到文章最初時提的兩個問題:
Q:為什麼同一個字元串,使用GBK和UTF-8進行編碼後的位元組數不一樣?
A:因為GBK對於一個字元,恆定使用兩個位元組來表示,但是UTF-8會使用1~4個位元組來表示。而文章開頭時,給出的示例字元串為三個漢字「哈哈哈」,在UTF-8中,一個漢字會用三個位元組來表示。所以gbk編碼後,位元組數為2 * 3 = 6,而UTF-8編碼後,位元組數為3 * 3 = 9.
Q:為什麼在獲取位元組數時,不指定charset的結果與指定使用UTF-8時相同?
A:可以看一下getByte()的源碼,如下:
繼續看958行的encode方法:
注意看384行,會取默認的charset,繼續跟下去:
看608行,取得時系統屬性file.encoding,以此作為默認的編碼方式。
驗證一下,如下:
CCS、CES、CEF、碼元的概念,皆引用自知乎專欄( https://zhuanlan.hu.com/p/27026033 ),不保證正確性與通用性,不過個人認為這幾個概念,對於理解unicode、UTF等有著極大的幫助。
❻ 常見的編碼方式
一、ASCII 碼
我們知道,計算機內部,所有信息最終都是一個二進制值。每一個二進制位(bit)有0和1兩種狀態,因此八個二進制位就可以組合出256種狀態,這被稱為一個位元組(byte)。也就是說,一個位元組一共可以用來表示256種不同的狀態,每一個狀態對應一個符號,就是256個符號,從00000000到11111111。
上個世圓慧滑紀60年代,美國制定了一套字元編橘臘碼,對英語字元與二進制位之間的關系,做了統一規定。這被稱為 ASCII 碼,一直沿用至今。
ASCII 碼一共規定了128個字元的編碼,比如空格SPACE是32(二進制00100000),大寫的字母A是65(二進制01000001)。這128個符號(包括32個不能列印出來的控制符號),只佔用了一個位元組的後面7位,最前面的一位統一規定為0。
二、非 ASCII 編碼
英語用128個符號編碼就夠了,但是用來表示其他語言,128個符號是不夠的。比如,在法語中,字母上方有注音符號,它就無法用 ASCII 碼表示。於是,一些歐洲國家就決定,利用位元組中閑置的最高位編入新的符號。比如,法語中的é的編碼為130(二進制10000010)。這樣一來,這些歐洲國家使用的編碼體系,可以表示最多256個符號。碧罩
但是,這里又出現了新的問題。不同的國家有不同的字母,因此,哪怕它們都使用256個符號的編碼方式,代表的字母卻不一樣。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (ג),在俄語編碼中又會代表另一個符號。但是不管怎樣,所有這些編碼方式中,0--127表示的符號是一樣的,不一樣的只是128--255的這一段。
至於亞洲國家的文字,使用的符號就更多了,漢字就多達10萬左右。一個位元組只能表示256種符號,肯定是不夠的,就必須使用多個位元組表達一個符號。比如,簡體中文常見的編碼方式是 GB2312,使用兩個位元組表示一個漢字,所以理論上最多可以表示 256 x 256 = 65536 個符號。
中文編碼的問題需要專文討論,這篇筆記不涉及。這里只指出,雖然都是用多個位元組表示一個符號,但是GB類的漢字編碼與後文的 Unicode 和 UTF-8 是毫無關系的。
三. Unicode
正如上一節所說,世界上存在著多種編碼方式,同一個二進制數字可以被解釋成不同的符號。因此,要想打開一個文本文件,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現亂碼。為什麼電子郵件常常出現亂碼?就是因為發信人和收信人使用的編碼方式不一樣。
可以想像,如果有一種編碼,將世界上所有的符號都納入其中。每一個符號都給予一個獨一無二的編碼,那麼亂碼問題就會消失。這就是 Unicode,就像它的名字都表示的,這是一種所有符號的編碼。
Unicode 當然是一個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,U+4E25表示漢字嚴。具體的符號對應表,可以查詢unicode.org,或者專門的漢字對應表。
❼ 計算機字元編碼都有哪些
計算機通用的字元編碼:ASCII碼
ASCII(American Standard Code for Information Interchange,美國信息互換標准代碼)是基於拉丁字母的一套電腦編碼系統。它主要用於顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,並等同於國際標准ISO/IEC 646。
❽ 目前國際上通用的計算機字元編碼
目前國際上通用的計算機字元編神遲碼主要有ASCII、GB2312、GBK、Unicode。根據查詢相關資料信息顯示,字元編碼(英語:Characterencoding)也稱字集游賀碼,是把字元集中的字元編碼為指定集合中某一對象(例如:比特模式、自然數序列、8位組或者電脈沖),以便文本在計算機中存儲和通過通信網路的傳遞。常見的例子包括將拉丁字母表編碼成摩斯電碼和ASCII。其中,ASCII將字母、數字和其它符號編號,神瞎派並用7比特的二進制來表示這個整數。通常會額外使用一個擴充的比特,以便於以1個位元組的方式存儲。
❾ 信息編碼方式有哪些
編碼方式有哪些_簡述常用的編碼方式
1、ASCII碼
學過計算機的人都知道ASCII碼,總共有128個,用一個位元組的低7位表示,0~31是控制字元如換行回車刪除等;32~126是列印字元,可以通過鍵盤輸入並且能夠顯示出來。
2、ISO-8859-1
128個字元顯然是不夠用的,於是ISO組織在ASCII碼基礎上又制定了一些列標准用來擴展ASCII編碼,它們是ISO-8859-1~ISO-8859-15,其中ISO-8859-1涵蓋了世桐大多數西歐語言字元,所有應用的最廣泛。ISO-8859-1仍然是單位元組編碼,它總共能表示256個字元。
3、GB2312
它的全稱是《信息交換用漢字編碼字元集基本集》,它是雙位元組編碼,總的編碼范圍是A1-F7,其中從A1-A9是符號區,總共包含682個符號,枯段從B0-F7是漢字區,包含6763個漢字。
4、GBK
全稱叫《漢字內碼擴展規范》,是國家技術監督局為windows95所制定的新的漢字內碼規范,它的出現是為了擴展GB2312,加入更多的漢字,它的編碼范圍是8140~FEFE(去掉XX7F)總共有23940個碼位,它能表示21003個漢字,它的編碼是和GB2312兼容的,也就是說用GB2312編碼的漢字可以用GBK來解碼,並且不會有亂碼。
5、GB18030
全稱是《信息交換用漢字編碼字元集》,是我國的強制標准,它可能是單位元組、雙位元組或者四位元組編碼,它的編碼與GB2312編碼兼容,這沒返譽個雖然是國家標准,但是實際應用系統中使用的並不廣泛。
6、UTF-16
說到UTF必須要提到Unicode(UniversalCode統一碼),ISO試圖想創建一個全新的超語言字典,世界上所有的語言都可以通過這本字典來相互翻譯。可想而知這個字典是多麼的復雜,關於Unicode的詳細規范可以參考相應文檔。Unicode是Java和XML的基礎,下面詳細介紹Unicode在計算機中的存儲形式。
UTF-16具體定義了Unicode字元在計算機中存取方法。UTF-16用兩個位元組來表示Unicode轉化格式,這個是定長的表示方法,不論什麼字元都可以用兩個位元組表示,兩個位元組是16個bit,所以叫UTF-16。UTF-16表示字元非常方便,每兩個位元組表示一個字元,這個在字元串操作時就大大簡化了操作,這也是Java以UTF-16作為內存的字元存儲格式的一個很重要的原因。
7、UTF-8
UTF-16統一採用兩個位元組表示一個字元,雖然在表示上非常簡單方便,但是也有其缺點,有很大一部分字元用一個位元組就可以表示的現在要兩個位元組表示,存儲空間放大了一倍,在現在的網路帶寬還非常有限的今天,這樣會增大網路傳輸的流量,而且也沒必要。而UTF-8採用了一種變長技術,每個編碼區域有不同的字碼長度。不同類型的字元可以是由1~6個位元組組成。
UTF-8有以下編碼規則:
如果一個位元組,最高位(第8位)為0,表示這是一個ASCII字元(00-7F)。可見,所有ASCII編碼已經是UTF-8了。
如果一個位元組,以11開頭,連續的1的個數暗示這個字元的位元組數,例如:110xxxxx代表它是雙位元組UTF-8字元的首位元組。
如果一個位元組,以10開始,表示它不是首位元組,需要向前查找才能得到當前字元的首位元組。