各种编码格式(GB2312,GBK,GB18030,unicode,utf-8)之间的关系
漢字常用編碼格式
為了在屏幕上顯示字符。需要下面幾個步驟:
第1個步驟的工作也就是我們常見的制作字體,比如宋體、楷體等。它只關心字符的長相。而第二、三個步驟有些是一起做的。如GB2312、GB18030的編碼方式。有些是分開的,如unicode編碼指做了第而步驟,而將第三步驟交給了utf-8、utf-16、utf-32等。
計算機在屏幕上顯示字符的流程是,加載存儲好的文本,通過編碼方式解析出字符編碼,然后通過字符編碼找到對應的字符字模,然后顯示。由于計算機的發展是一步步迭代的,由于之前的編碼方式不能滿足后續的工作需求,所以出現了很多中的編碼方式。如我們常見的GB2312、utf-8等。下圖是常用編碼方式之間的關系圖:
GB18030、GBK、GB2312漢字編碼格式
GB2312編碼
GB2312編碼是第一個漢字編碼國家標準,由中國國家標準總局1980年發布,1981年5月1日開始使用。GB2312編碼共收錄漢字6763個,其中一級漢字3755個,二級漢字3008個。同時,GB2312編碼收錄了包括拉丁字母、希臘字母、日文平假名及片假名字母、俄語西里爾字母在內的682個全角字符。。它使用2個字節編碼,編碼范圍為A1A1~FEFE。其中首字節叫區,尾字節叫位。共A1~FE94個區,每個區包含A1~FE94個位。共94*94=8836個碼位。
GBK編碼
GB2312支持的漢字太少。1995年的漢字擴展規范GBK1.0收錄了21886個符號,它分為漢字區和圖形符號區。漢字區包括21003個字符。GBK中的K為漢語拼音擴的聲母,即擴展的含義。英文全稱Chinese Internal Code Specification。GBK編碼標準兼容GB2312。GB2312基本滿足了漢字的計算機處理需要,但對于人名、古漢語等方面出現的罕用字,GB2312不能處理,這導致了后來GBK及GB18030漢字字符集的出現。GBK采用雙字節表示,總體編碼范圍為8140-FEFE,首字節在81-FE之間,尾字節在40-FE之間,剔除xx7F一條線。總計23940個碼位,共收入21886個漢字和圖形符號.
GB18030編碼
在2000年,GB18030取代GBK1.0,正式國家標準。它的主要特點是在GBK基礎上增加了CJK統一漢字擴充A的漢字(GB18030-2000)。后又在此基礎上增加了CJK統一漢字擴充B的漢字(GB18030-2005)。
GB18030編碼格式有單字節、雙字節、四字節三種方案。其中單、雙字節的編碼和GBK完全兼容。4字節的編碼內容為CJK擴展A的6582個漢字。
unicode編碼及格式
unicode官網:https://www.unicode.org
上面提到的GBxxx都是我們國家定義的標準,當然只針對我們公家的漢字以及ASCII等。而unicode的出現是為了解決全球的字符編碼。以滿足跨語言、跨平臺進行文本轉換、處理的要求。這樣我們就可以在一篇文章中用n國語言來寫我愛你了。
unicode與UCS-2、UCS-4
早期 Unicode 在編制通用字符集之時,ISO 組織也在做同樣的事情,ISO 開展了 ISO/IEC 10646 項目,名字叫“ Universal Multiple-Octet Coded Character Set”,中文譯為“通用多八位編碼字符集”,英文簡稱UCS。后來雙方整合,到 Unicode 2.0 時,Unicode 編碼和 UCS 編碼都基本一致。
UCS-2 采用 16 位存儲空間,兩個字節編碼每個字符,而 UCS-4 采用 4 個字節(實際上只用了 31 位,最高位必須為 0)編碼。
UCS-4 根據最高位為 0 的最高字節分成27=128個組(group)。每個組再根據次高字節分為256個平面(plane)。每個平面根據第3個字節分為256行(rows),每行包含256個單元(cells)。當然同一行的單元只是最后一個字節不同,其余都相同。
0組的0號平面被稱作Basic Multilingual Plane,即基本多文種平面,簡寫BMP。可知BMP區域內的字符只使用了兩個字節,碼位從 U+0000 至 U+FFFF。它實際上就是 UCS-2 的全部編碼范圍,后來因為碼位不夠用才擴展為 UCS-4。
17個平面中目前只用到0號、1號、2號和14號平面,其中漢字在0號平面和2號平面,其它文字在0號、1號和14號平面;
具體的漢字Unicode編碼范圍見此鏈接:https://www.qqxiuzi.cn/zh/hanzi-unicode-bianma.php.
utf-8、utf-16、utf-32編碼格式
要說unicode與utf-8、utf-16、utf-32之間的關系,我們須明確編碼格式=編碼+存儲格式。其中編碼對應文章開頭提到的第二個步驟,存儲格式對應第三個步驟。unicode只是編碼,不涉及存儲格式。而utf-x是基于unicode編碼的編碼格式。清楚這點,我們也就清楚了utf-8、utf-16、utf-32三者的關系。它們的都使用unicode編碼,那肯定存儲格式存在差異,因此起了三個名唄。說到這兒,會有一個疑問?那GB2312、GBK等的編碼和存儲格式分別是什么了?其實,GB2312、GBK等是將編碼和存儲格式整合到了一起。因為GB2312的編碼是從A1A1~FEFE,它和ASCII(0x00~0x7F)在字節流上本身就不沖突。當文本中的字節小于0x80,他一定為ASCII碼。而當文本中的字節大于0x80時,此字節加下一個字節共同表示一個漢字。而unicode編碼就不同了,它的字符編碼中的每個字節都可以小于0x80,那么它的這個字節代表ASCII呢還是和其他字節組合表示一個別的字符(如漢字)?沒法確定,所以必須要有存儲格式。下面將談論它們的編碼格式。
utf-8編碼格式
utf-8官網:http://www.utf-8.com/
utf-8(Unicode Transformation Format 8-bit)是一種可變寬度的編碼格式。用1~4個字節表示一個Unicode字符編碼。它可以表示unicode字符集中的所有字符。
utf-8編碼格式:
如編碼0b1110xxxx,0b10xxxxxx,0b10xxxxxx表示一個三字節的編碼格式,其中x代表的是可編碼的位置。可以計算出三字節編碼格式共有2^24個編碼位置。
如表是1~4字節的具體編碼格式表:
| 0b0xxxxxxx | 0x00~0x7F |
| 0b110xxxxx 0b10xxxxxx | 0x80~0x7FF |
| 0b1110xxxx 0b10xxxxxx 0b10xxxxxx | 0x800~0xFFFF |
| 0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx | 0x10000~0x10FFFF |
上面是存儲格式,那如何將unicode字符編碼填充到utf-8的格式里了?
unicode編碼轉化為utf-8編碼的步驟如下:
再舉個例子:漢字郭的unicode字符編碼為0x90ED(0b10010000,11101101),由0x800 < 0x90ED < 0xFFFF得到它的編碼格式為utf-8的3字節編碼格式。然后將其二進制0b10010000,11101101填入0b1110xxxx 0b10xxxxxx 0b10xxxxxx后為0b11101001,10000011,10101101=0xE983AD.也就是utf-8字符郭的編碼值。
有了utf-8與unicode之間的關系,就很容易寫出轉換程序。下面是c語言實現的utf-8編碼轉unicode編碼
/* * utf-8字符編碼轉化為unicode編碼。(2字節模式)* pIn:要轉換的字符串首地址* charsize:接收返回的utf8字符的字節數(1~3)* pOut:獲取到的UCS2編碼,pOut[0]為首字節。*/ int Utf8ToUCS2(const char *pIn,char *charsize,char *pOut) {uint8_t firstValue = *pIn;char *pUCS2 = pOut;if(firstValue < 0x80){//0~127 ASCII 1bytepUCS2[0] = 0;pUCS2[1] = *pIn;*charsize = 1;}else if( (firstValue & 0xE0) == 0xC0){//128~2047 2byteif( (pIn[1] & 0xC0) != 0x80){return -1;}pUCS2[0] = (pIn[0] & 0x1F) >> 2;pUCS2[1] = (pIn[0] << 6) + (pIn[1] & 0x3F);*charsize = 2;}else if( (firstValue & 0xF0) == 0xE0){//2048~65536 3byteif( (pIn[1] & 0xC0) != 0x80 || (pIn[2] & 0xC0) != 0x80){return -1;}pUCS2[0] = (pIn[0] << 4) + ((pIn[1] & 0x3F) >> 2);pUCS2[1] = (pIn[1] << 6) + (pIn[2] & 0x3F);*charsize = 3;}else {//>3byte不處理,漢字用不到4字節的編碼*charsize = 0;return -1;}return 0; }漢字編碼轉換工具及編碼表
1.千千秀字:https://www.qqxiuzi.cn/daohang.htm 這個網站上有編碼之間的轉換、編碼值查詢、漢字碼值表等編碼相關的工具。
關于技術交流
此處后的文字已經和題目內容無關,可以不看。
qq群:825695030
微信公眾號:嵌入式的日常
如果上面的文章對你有用,歡迎打賞、點贊、評論。
總結
以上是生活随笔為你收集整理的各种编码格式(GB2312,GBK,GB18030,unicode,utf-8)之间的关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么叫水平,不是看懂了叫水平,也不是会用
- 下一篇: 机房环境监控系统品牌-深圳计通