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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

字符集与编码(四)——Unicode

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

2019獨角獸企業重金招聘Python工程師標準>>>

注:由于兩邊同步的麻煩,更多更改及調整可參考我的網站:xiaogd.net 上的字符集編碼與亂碼系列,已將字符集編碼系列與亂碼探源系列合并,更新及勘誤等不再更新到這邊。

前面談到不少的Unicode,但一直沒有系統地談及Unicode的方方面面,所以本篇文章專門談談Unicode,當然了,Unicode是一個龐大的主題,這里也是揀些重要的方面談談而已,免不了掛一漏萬。

什么是Unicode?

按Unicode官方的說法,Unicode是Unicode Standard(Unicode標準)的簡寫,所以Unicode即是指Unicode標準。

按wiki的說法,它是一個計算機工業標準(a computing industry standard)。

下圖來自http://www.unicode.org/standard/WhatIsUnicode.html中的截圖,在這里我把中文和英文的合在一起

這樣一個所謂的一個唯一的數字在Unicode中就叫做碼點

Unicode中的碼點是什么?

字符集通常又叫”編碼字符集”(coded charset),這里的coded與”字符集編碼”(charset encoding)中的encoding是不同的。

一個是code,一個是encode,翻譯時都可以譯成”編碼”,但把coded charset譯成”編號字符集”也許更不易引發誤解。

碼點(Code Point)即是這里的code,表示的是一種抽象的數字編號。UTF-X則是最終的encoding。

這點如不明白,仍請參見字符集與編碼(二)--編號 vs 編碼。

碼點的表示形式與范圍是?

U+[XX]XXXX是碼點的表示形式,X代表一個十六制數字,可以有4-6位,不足4位前補0補足4位,超過則按是幾位就是幾位。以下是碼點的一些具體示例:U+0048,U+4F60,U+1D11E。最后一個是5位的碼點。

有人可能以為碼點只有4位,并常常將它與UTF-16的編碼搞混,這些都是對碼點的誤解。

它的范圍目前是U+0000~U+10FFFF,理論大小為10FFFF+1=110000。后一個1代表是65536,因為是16進制,所以前一個1是后一個1的16倍,所以總共有1×16+1=17個的65536的大小,粗略估算為17×6萬=102萬,所以這是一個百萬級別的數。

準確的值是1114112,一般記為111萬左右即可。

110000寫成二進制是100010000000000000000,是一個21位的二進制數,我們知道2^10=K,2^20=K×K=M,即百萬級別,所以2^21理論上限是兩百萬左右。100010000000000000000大小基本上由第一個1決定,所以也就一百萬左右,從這里也可印證前面的估算。

按照Unicode官方的說法,碼點范圍就這些了,以后也不會再擴充了。

為了更好分類管理如此龐大的碼點數,把每65536個碼點作為一個平面,總共17個平面。

平面,BMP,SP

什么是平面?

由前面可知,碼點的全部范圍可以均分成17個65536大小的部分,這里面的每一個部分就是一個平面(Plane)。編號從0開始,第一個平面稱為Plane 0.

下圖來自http://rishida.net/docs/unicode-tutorial/part2

什么是BMP?

第一個平面即是BMP(Basic Multilingual Plane 基本多語言平面),也叫Plane 0,它的碼點范圍是U+0000~U+FFFF。這也是我們最常用的平面,日常用到的字符絕大多數都落在這個平面內。

上圖中第一個花花綠綠的平面就是BMP。

UTF-16只需要用兩字節編碼此平面內的字符。

很多人錯誤地把UTF-16當成定長兩字節看待,但只要處理的字符都在這一平面內,一般也不會遇到什么問題。

什么是增補平面?

后續的16個平面稱為SP(Supplementary Planes)。顯然,這些碼點已經是超過U+FFFF的了,所以已經超過了16位空間的理論上限,對于這些平面內的字符,UTF-16采用了四字節編碼。

注:其中很多平面還是空的,還沒有分配任何字符,只是先規劃了這么多。

另:有些還屬于私有的,如上圖中的最后兩個Private Use Planes,在此可自定義字符。

鳥瞰BMP字符集

Unicode的字符如此之多,即使是最常用的BMP,它的碼點空間也有6萬多,如果把這些字符都放到一張圖片上,會是什么情況呢?GNU Unifont就制作了一張這樣的圖片。見http://unifoundry.com/pub/unifont-7.0.03/unifont-7.0.03.bmp

提示:打開它需要一點時間,它的像素是4000×4000這個級別!

下圖是它的一個縮略版本。

這是一個256×256=65536的表格,橫向縱向都是從00~FF。

CJK統一漢字

你可能已經注意到上圖中間一大片的區域,沒錯,它就是我們的漢字,在Unicode中,稱為CJK統一漢字(CJK:Chinese, Japanese, and Korean,中日韓)。我們可以局部放大看一下。

正則表達式[\u4E00-\u9FA5]來匹配中文的問題在哪?

你可能在不少地方見過這種寫法,嚴格來說這只是Unicode最主要的一段中文區域。

你只要稍加計算就可知這一段大小不過是兩萬多一點,\u4E00-\u9FA5(19968-40869),中文怎么可能只有這兩萬多字呢?

這里的“天字第一號”字4E00是哪個字呢?請看上面的圖,它就是“一“字,我們還可以看到它上面還有不少的漢字,這就是后來增補的漢字了。所以嚴格來說,這個上限是不準確的。那么它的下限又是否準確呢?下面是Word的一個插入符號功能的一個截圖

可以看到9FA5后面也還有不少的漢字,它們中間又還夾雜著一些符號,所以想正確地表示Unicode中的漢字還是個不小的挑戰。

應該說,Unicode處在不斷發展中,它有一百多萬的空間,目前也只是定義了十萬左右的字符,還會不斷增加,漢字自然也有可能增加,所以漢字的范圍實際上是動態的,變化的。當然了,常用的基本落在了這一范圍內,而事實上已經包含了許多的不常用漢字,畢竟連只有6千多字的GB2312中都含有大量的不常用漢字。在要求不那么嚴格的應用中,按以上范圍去判斷基本也OK,而“漢字”這一概念實際上也沒有準確定義,比方說上圖中一些“偏旁部首”,這些是“漢字”嗎?

代理區

你可能還注意到前面的BMP縮略圖中有一片空白,這白花花一片亮瞎了我們的猿眼的是啥呢?正如標題已經告訴你的,這就是所謂的代理區(Surrogate Area)了。

可以看到這段空白從D8~DF。其中前面的紅色部分D800–DBFF屬于高代理區(High Surrogate Area),后面的藍色部分DC00–DFFF屬于低代理區(Low Surrogate Area),各自的大小均為4×256=1024。

關于代理區的相關用途,我們在講到UTF-16編碼時再說。

還可以看到在它之前是韓文的區域,之后E0開始到F8的則是屬于私有的(private),可以在這里定義自己專用的字符。

至此我們對Unicode的碼點,平面都有了一定的了解,但我們還沒有觸及一個重要的方面,那就是碼點到最終編碼的轉換,在Unicode中,這稱為UTF。

什么是UTF?

UTF即是Unicode轉換格式(Unicode (or UCS) Transformation Format)

關于UCS:Universal Character Set(統一字符集),也稱ISO/IEC 10646標準,不那么嚴格的情況下,可以認為它和”Unicode字符集“這一概念是等價的。如有興趣的可以自行搜索了解。

碼點如何轉換成UTF的幾種形式呢?我想這是大家很關心的問題,再發一次前面的一個圖

讓我們先從最簡單的UTF-32說起

UTF-32

我們說碼點最大的10FFFF也就21位,而UTF-32采用的定長四字節則是32位,所以它表示所有的碼點不但毫無壓力,反而綽綽有余,所以只要把碼點的表示形式以前補0的形式補夠32位即可。這種表示的最大缺點是占用空間太大。

再來看稍復雜一點的UTF-8。

UTF-8

UTF-8是變長的編碼方案,可以有1,2,3,4四種字節組合。在前面的定長與變長篇章我們提到UTF-8采用了高位保留方式來區別不同變長,如下:

如上,彩色的表示是保留的固定位,X表示是有效編碼位。

單字節最高位都是0,多字節的最高位都是1.

多字節方面,更具體的講,N字節模式,首字節以“N個1再加0”打頭,后跟“N-1”個以“10”打頭的字節。

碼點與字節如何對應?

哪些碼點用哪種變長呢?可以先把碼點變成二進制,看它有多少有效位(去掉前導0)就可以確定了。

1. 一字節有效編碼位有7位,2^7=128,碼點U+0000~U+007F(0~127)使用一字節。

一字節留給了ASCII,所以UTF-8兼容ASCII。

2. 二字節有效編碼位只有5+6=11位,最多只有2^11=2048個編碼空間,所以數量眾多的漢字是無法容身于此的了。碼點U+0080~U+07FF(128~2047)使用二字節。

注意:這里碼點從128~2047,因為去掉了一字節的碼點,所以不會占滿2048個編碼空間,是有冗余的,但你不能把適用于一字節的碼點放到這里來編碼。下同。

3. 三字節模式可看到光是保留位就達到4+2+2=8位,相當一字節,所以只剩下兩字節16位有效編碼位,它的容量實際也只有65536。碼點U+0800~U+FFFF(2048~65535)使用三字節編碼。

我們前面說到,一些漢字字典收錄的漢字達到了驚人的10萬級別?;旧?#xff0c;常用的漢字都落在了這三字節的空間里,這就是我們常說的漢字在UTF-8里用三字節表示。當然了,這么說并不嚴謹,如果這10萬的漢字都被收錄進來的話,那些偏門的漢字自然只能被擠到四字節空間上去了。

4. 四字節的可以看到它的有效位是3+6+6+6=21位,前面說到最大的碼點10FFFF也是21位,U+FFFF以上的增補平面的字符都在這里來表示。

按照UTF-8的模式,它還可以擴展到5字節,乃至6字節變長,但Unicode說了碼點就到10FFFF,不擴充了,所以UTF-8最多到四字節就足夠了。

碼點到UTF-8如何轉換?

那么具體是如何轉換呢,其實不難,來看一個漢字”你“(U+4F60)的轉換示意,如下圖所示:

上圖顯示了一有效位為15位的碼點到三字節轉換的一個基本原理,我們還可看到原來4F60中的一頭一尾的兩個4和0在轉換后還存在于最終的三字節結果中。UTF-8三字節模式固定了1110的開頭模式,所以多數漢字總是以1110開頭,換成16進制形式,1110就是字母E。

如果看到一串的16進制有如下的形式:EX XX XX EX XX XX…每三個三個字節前面都是E打頭,那么它很可能就是一串漢字的UTF-8編碼了。

其它變長字節轉換道理也類似,其中分組從低位開始,高位如不足則補零。這里就不再示例了。

最后來看最復雜的UTF-16,在此之前我們先要理解代理區與代理對等概念。

UTF-16

UTF-16是一種變長的2或4字節編碼模式。對于BMP內的字符使用2字節編碼,其它的則使用4字節組成所謂的代理對來編碼。

什么是代理區?

在前面的鳥瞰圖中,我們看到了一片空白的區域,這就是所謂的代理區(Surrogate Area)了,代理區是UTF-16為了編碼增補平面中的字符而保留的,總共有2048個位置,均分為高代理區(D800–DBFF)和低代理區(DC00–DFFF)兩部分,各1024,這兩個區組成一個二維的表格,共有1024×1024=2^10×2^10=2^4×2^16=16×65536,所以它恰好可以表示增補的16個平面中的所有字符。

當然了,說恰好是不對的,顯然代理區就是沖著表示增補平面來設計的,或者至少它們是一起考慮的。

下面的圖片來自wiki

什么是代理對?

一個高代理區(即上圖中的Lead(頭),行)的加一個低代理區(即上圖中的Trail(尾),列)的編碼組成一對即是一個代理對(Surrogate Pair),必須是這種先高后低的順序,如果出現兩個高,兩個低,或者先低后高,都是非法的。

在圖中可以看到一些轉換的例子,如

D8 00 DC 00)—>U+10000,左上角,第一個增補字符

DB FF DF FF)—>U+10FFFF,右下角,最后一個增補字符

碼點到UTF-16如何轉換?

分成兩部分:

1. BMP中直接對應,無須做任何轉換;

2. 增補平面SP中,則需要做相應的計算。其實由上圖中的表也可看出,碼點就是從上到下,從左到右排列過去的,所以只需做個簡單的除法,拿到除數和余數即可確定行與列。

拿到一個碼點,先減去10000(16進制),再除以400(16進制)(=1024(10進制))就是所在行了,余數就是所在列了,再加上行與列所在的起始值,就得到了代理對了。

Lead = (碼點 - 10000) ÷ 400?+ D800

Trail = (碼點 - 10000) % 400?+ DC00

下面以前面的U+1D11E具體示例了代理對的計算:

Lead = (1D11E - 10000) ÷ 400?+ DB00 = D11E ÷ 400?+ D800 = 34 + D800 = D834

Trail = (1D11E - 10000) % 400?+ DC00 = D11E % 400?+ DC00 = 11E + DC00 = DD1E

所以,碼點U+1D11E對應的代理對即是 D834 DD1E。

注意:以上計算方式僅用于說明轉換原理,不代表實際采用的計算方式。一個碼點減去1000016后實際最多只有20位,再除以400(=2^10=10000000000(2進制)),這個除數實際是一個二進制整數,相當于十進制中整十整百的數。所以結果實際上低10位上的就是余數,而高10位(或者不到10位)上就是商,可以通過更為快速的移位操作實現。舉個十進制的例子,就好比是“1234÷100=12??????34”,你都不需要拿筆去算。應該說,代理區的設計是有效率上的考慮的,如果我們要做轉換,應該考慮是否有系統API可供調用,而不要自行去實現。

關于Unicode的基本知識,就講到這里。

轉載于:https://my.oschina.net/goldenshaw/blog/310331

總結

以上是生活随笔為你收集整理的字符集与编码(四)——Unicode的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 青青草视频在线看 | 国产99久久久久久免费看 | 欧美一级免费视频 | 免费看成人| 成人动漫av | 久久久久玖玖 | 天堂v在线观看 | 国产高清免费av | 狠狠地日 | 毛片视频播放 | 亚洲成在线 | 精品少妇久久久 | 久草福利资源站 | 欧美日韩成人一区 | 亚洲视频天堂 | 强开小受嫩苞第一次免费视频 | 国产欧美日韩综合精品一区二区三区 | 中国 免费 av | 婷婷午夜精品久久久久久性色av | 成人欧美一区二区三区黑人 | 精品成人av | 一级激情片 | 亚洲国产精品成人综合色在线婷婷 | 欧美黄视频 | 国产精品色哟哟 | 日本精品一区 | 国产成人免费 | 99精品99 | 18禁免费观看网站 | 神马影院一区二区 | 国产欧美日韩一区二区三区 | youjizzcom日本 | 少妇搡bbbb搡bbb搡小说 | 国产无套粉嫩白浆内谢 | 欧美激情va永久在线播放 | 韩国三色电费2024免费吗怎么看 | 免费在线观看小视频 | 打开免费观看视频在线 | 天天综合天天做天天综合 | av影片在线 | 亚洲av无码国产精品永久一区 | 公侵犯人妻一区二区 | 免费a在线| 成人免费午夜视频 | 欧美成人综合一区 | 汗汗视频 | 日韩中文字幕在线 | 伊人成人动漫 | 69xx网站| 以女性视角写的高h爽文 | 伦理片久久 | 一区二区三区四区视频 | 国产午夜小视频 | 午夜精品久久久久久99热 | 成人性生交大片免费看vrv66 | 夜夜嗨av| 老司机深夜福利视频 | 99在线精品观看 | 一级黄色视屏 | 手机看片1024日韩 | 日韩精品一区二区在线看 | 中文字幕第页 | 视频一区二区三 | 婷婷色婷婷开心五月四房播播 | 国产做a | 久久久久免费精品 | 91免费网| 日本大胆裸体做爰视频 | 黄色片在线免费观看视频 | www99re| 国产aa | 精品一区二区三区av | 男人和女人日b视频 | 国产精品美女久久久免费 | 小少妇哺乳喂奶播放 | 黄片毛片在线免费观看 | 男女做受视频 | 成人精品影视 | 色爽黄 | 国产精品日韩一区二区三区 | 欧美一区二区精品 | 一卡二卡三卡在线 | 台湾佬综合网 | 国产精品一区在线 | 国产97自拍 | 国产又黄又爽 | 农村妇女毛片精品久久久 | 青青草成人免费在线视频 | 土耳其xxxx性hd极品 | 精品国产乱码久久久久久郑州公司 | 中文字幕人妻一区二区三区 | 夜夜精品一区二区无码 | 国产乱国产乱老熟300部视频 | 在线看成人 | 蜜桃av色偷偷av老熟女 | 天堂8在线 | 国产男人搡女人免费视频 | 无码少妇精品一区二区免费动态 | 亚洲一级无毛 |