[精讚] [會員登入]
3356

UTF8和unicode的轉換

常聽到的 unicode, utf8, ascii 又是什麼?utf8和unicode之間的關係及如何轉換?

分享此文連結 //n.sfs.tw/15670

分享連結 UTF8和unicode的轉換@新精讚
(文章歡迎轉載,務必尊重版權註明連結來源)
2022-03-11 17:43:21 最後編修
2022-03-11 09:54:21 By 張○○
 

自動目錄

常常看到有些文字會用 0x12AB 或是 0x0123AB、U+4AE0、&#1234 這種形式表示,這種寫法到底是什麼意思?和我們常用的文字之間有什麼關係?

常聽到的 unicode, utf8, ascii 又是什麼?utf8和unicode之間的關係及如何轉換?藉由此文整理並徹底了解。

Unicode

unicode 簡介

計算機起源於美國,上個世紀,他們制定了一套字符編碼規則,稱爲 ASCII 編碼。

ASCII 編碼一共定義了 128 個字符,裡面有英文大小寫數字、標點符號及一些控制用符號,這些字符組成的集合就叫做 ASCII 字符集。

隨着計算機的普及,在不同的地區和國家又出現了很多字符編碼,比如: 大陸的 GB2312、港臺的 BIG5, 日本的 Shift JIS 等等。[1]

但是由於字符編碼不同,文字在不同國家之間經常需要轉換,否則會出現亂碼,網際網路的出現這種情況越來越嚴重需要解決。於是1990開始就有許多機構致力於統一不同的文字編碼,於是 Unicode 就出現了,歷經幾十年的發展,成為現在看到的版本。

簡單來說,unicode 就是把現有的文字符號等加以編碼收集起來,有點類似一本超大字典,所以unicode 也可稱為通用字元集ucs(英語:Universal Character Set, UCS)[3]。

 

unicode的分組

目前的unicode字符分成17組,從U+0000 至 U+10FFFF,每組稱為編碼平面(Code Plane),每平面擁有65536個編碼點。

其中 U+0000 ~ U+FFFF 稱為基本多語言平面(Basic Multilingual Plane,簡記為BMP),也叫做平面0。平面0包含了世界上多種文字。

其餘劃入16個輔助平面(Supplementary Plane),編碼點範圍U+10000 ~ U+10FFFF。

其中平面0的中文字群範圍:

4E00-9FBF:CJK 統一表意符號(CJK Unified Ideographs) 包含漢字

總共有40895-19968= 20927個漢字

其餘分群請看[6]

 

目前的Unicode字符分為17組編排,U+0000 至 U+10FFFF,每組稱為代碼平面(Code Plane),每平面擁有65536(2的16次方)個代碼點。

  • U+0000 ~ U+FFFF劃入基本多語言平面(Basic Multilingual Plane,簡記為BMP),也叫做平面0。平面0包含了世界上多種文字。
  • 其餘劃入16個輔助平面(Supplementary Plane),代碼點範圍U+10000 ~ U+10FFFF。輔助平面中的文字通常使用不上。


原文網址:https://kknews.cc/code/o5jgy8q.html

目前的Unicode字符分為17組編排,U+0000 至 U+10FFFF,每組稱為代碼平面(Code Plane),每平面擁有65536(2的16次方)個代碼點。

  • U+0000 ~ U+FFFF劃入基本多語言平面(Basic Multilingual Plane,簡記為BMP),也叫做平面0。平面0包含了世界上多種文字。
  • 其餘劃入16個輔助平面(Supplementary Plane),代碼點範圍U+10000 ~ U+10FFFF。輔助平面中的文字通常使用不上。


原文網址:https://kknews.cc/code/o5jgy8q.html

目前的Unicode字符分為17組編排,U+0000 至 U+10FFFF,每組稱為代碼平面(Code Plane),每平面擁有65536(2的16次方)個代碼點。

  • U+0000 ~ U+FFFF劃入基本多語言平面(Basic Multilingual Plane,簡記為BMP),也叫做平面0。平面0包含了世界上多種文字。
  • 其餘劃入16個輔助平面(Supplementary Plane),代碼點範圍U+10000 ~ U+10FFFF。輔助平面中的文字通常使用不上。


原文網址:https://kknews.cc/code/o5jgy8q.html

unicode 表示方法

在表示一個Unicode的字元時,通常會用「U+」或小寫的「u+」然後緊接著多組十六進位的數字來表示這一個字元。例如

U+50

U+3105

u+0123AB

程式語言有時會用 0x代替 U+,例如

0x3105

 

網頁上的表示方法

如果想在網頁上呈現unicode,把 'U+' 替換成 '&#',把十六進位的編碼換成十進位,最後在字元的結束加上分號即可,例如顯示注音符號的ㄅ,查碼發現編碼是u+3105,

要把3105換成10進位,即12549,那在網頁上打上

ㄅ

就會出來注音符號的ㄅ。

 

PHP上顯示unicode[4]

print 0x3105;  //12549

json_decode('"\u3105"');  //ㄅ

 

查詢unicode

那要怎麼知道文字的unicode編碼?當然如果可以直接打出來的字不必理會他的編碼,但有些字是以現有的輸入法打不出來的,這時就可以使用查表的方法

可以參考以下網站(2022.3):

unicode有分類清單 https://jicheng.tw/hanzi/unicode?s=9F9C&e=9F9C&font= ;;; (推薦[6])

全字庫 https://www.cns11643.gov.tw/searchQ.jsp?ID=0

unicode清單有轉10進位 https://www.ifreesite.com/unicode/character.htm

 

UTF8

unicode是字元集,要實現的話還是得靠編碼系統,其中有名的有 utf8, utf16, ucs2, ucs4等等。

根據w3tech[5]的研究,到了2022.3,utf8已占了網頁中全部編碼系統的 98%。其餘編碼雖然仍存在諸多系統中,但使用數量已漸漸示微。

 

UTF8的編碼方式

UTF-8是一種非固定長度字節編碼方式。最長可達6個bytes(以下稱為字節)組成一個字,最短只需1個byte。這樣的好處是他相容於ascII的編碼方式。

以下是 UTF-8 的編碼原則(2進位)。

1字節 0xxxxxxx
2字節 110xxxxx 10xxxxxx
3字節 1110xxxx 10xxxxxx 10xxxxxx
4字節 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字節 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字節 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

舉例如下,粉底代表定義的指定位元:

A=> 65 => 01000001  <== 等同於ASCII

и=> 208 184 =>  11010000 10111000

錢=>233 140 162 => 11101001 10001100 10100011

ね=>227 129 173  => 11100011 10000001 10101101

一隻豬(請看下圖)=>240,147,131,159  =>11110000 10010011 10000011 10011111

四個字節的字有些電腦無法正確顯示,請參考上圖。

簡單的判斷方法,第一個字節2進位有幾個1開頭就是幾個字節的UTF8字。

 

各字節組擁有的字數

1字節 0xxxxxxx => 2^7= 128個
2字節 110xxxxx 10xxxxxx => 2^(5+6)= 2048
3字節 1110xxxx 10xxxxxx 10xxxxxx => 2^(4+6+6)= 65536
4字節 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx => 2^(3+6+6+6)=2097152
5字節 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx => 67108864
6字節 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx =>2147483648

基本上用3個字節就足以涵蓋67000個字、4個字節就足以涵蓋215萬個字,五個字節以上的字目前沒有。

 

UTF8和unicode 之間的轉換

UTF8是變動字節長,而unicode 是固定字節,這兩者之間如何轉換?

 

unicode轉成 UTF8

Unicode 的字節編碼對照UTF8的編碼方式

直接用範例作說明,例如中文字的「錢」unicode 是 U+9322

1. 因為是9322,屬於平面0 000800~00FFFF這個範圍,也就是三字碼UTF8

2. 9322 => 93 22 (16進位)=> 10010011 00100010 (2進位) => 16個位元拆成 4, 6, 6 分組

  => 10010011 00100010

3. 將分成的3組代換掉 UTF8 的xxxx..

 11101001 10001100 10100010  => 233  140 162  (10進位)

利用PHP來驗證

print chr(233).chr(140).chr(162);

結果

 

UTF8轉成unicode

由UTF8 轉成unicode 只要倒過來運算即可。

以剛才的錢字為例:

1. 取得UTF8 編碼 233 140 162

2. 轉成二進位 11101001 10001100 10100010 

3. 把顏色的部分組合=> 10010011 00100010

4. 8個位元一組轉成16進位=>93 22

5. U+9322完成

 

參考資料

[1] https://www.readfog.com/a/1638084002220969984

[2] https://zh.wikipedia.org/wiki/Unicode

[3] https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E5%AD%97%E7%AC%A6%E9%9B%86

[4] https://stackoverflow.com/questions/17539412/print-unicode-characters-php

[5] https://w3techs.com/technologies/cross/character_encoding/ranking

[6] https://jicheng.tw/hanzi/unicode?s=9F9C&e=9F9C&font=

 

END

你可能感興趣的文章

台灣2025(民國114年)節慶國定假日 ics下載 找不到2025年的假日ics檔?沒關係,我自己做一個。

網頁的結構化--為網頁加入自己的搜尋 網頁有原生的搜尋引擎,想把這個引擎交給搜尋引擎顯示。

如何開啟 .sqlite 的檔 如何開啟 .sqlite 的檔?

使用Google尋找你的手機 這近發現google竟然可以用來找android的手機,而且不需要經過什麼設定或安裝軟體。

手動清除 Firefox, Chrome的DNS cache Firefox, Chrome上有別於系統的DNS cache,有時會造成使用者刷新到舊的網頁

台灣2020(民國109年)節慶國定假日 ics下載 找不到2020的假日檔,沒關係,我自己做一個

隨機好文

Linux shell 的date表示法 linux下SHELL中的date表示法

看懂DSUB DVI HDMI USB等各式影音接頭 看懂DSUB DVI HDMI等各式影音接頭

[PHP]解決ksort新增的SORT_NATURAL|SORT_FLAG_CASE方法 php>=5.4中ksort函數多了SORT_NATURAL 和 SORT_FLAG_CASE 旗標,對舊版的PHP中要怎麼辦?

[AS3] FLASH 引入外部as檔 FLASH AS3中,若要引用另外撰寫的 class(*.as) 檔案,該如何處理?

McJob 淺談 在英語世界裡,近期多了一個英文生字 Mcjob,定義為「低薪、無聊且沒有什麼前景的工作」。