Unicode,UTF-8和UTF-16的區別與聯絡 - IT人
文章推薦指數: 80 %
但是對於中文等遠東字符集來說,就比較坑爹了。
char str[]; str[0]並不能完整表示一個漢字。
UTF-8編碼格式下,一個漢字需要至少3個char才能表示 ...
Togglenavigation
IT人
IT人
Unicode,UTF-8和UTF-16的區別與聯絡
pythontab發表於
2019-05-10
概念先說一說基本的概念,這包括什麼是Unicode,什麼是UTF-8,什麼是UTF-16。
Unicode,UTF-8,UTF-16完整的說明請參考Wiki(Unicode,UTF-8,UTF-16)。
用比較簡單的話來說就是,Unicode定義了所有可以用來表示字元的數值集合(稱之為CodePoint)。
UTF-8和UTF-16等UTF標準定義了這些數值和字元的對映關係。
UTF-8優勢UTF-8最大的優勢是,沒有位元組序的概念。
所以特別適合用於字串的網路資料傳輸,不用考慮大小端問題。
對於非英文網頁(對於我們而言,簡單說東亞文字網頁),能夠避免各種亂碼問題。
劣勢本地字串處理過程中,如果使用UTF-8,對於英文字元的處理沒有太大的問題。
一個char變數表示一個英文字元。
但是對於中文等遠東字符集來說,就比較坑爹了。
charstr[];str[0]並不能完整表示一個漢字。
UTF-8編碼格式下,一個漢字需要至少3個char才能表示。
這對於通過下標來操作字串的操作來說是非常痛苦的一件事情。
另外,一個漢字需要至少3個char來表示,也讓漢字在網路傳輸上存在劣勢,佔用太多流量(但是如果啟用了壓縮,實際上差別並不大。
並且現在很多中文網站都預設將編碼從GBK改成了UTF-8)。
UTF-16優勢UTF-16LE是windows上預設的Unicode編碼方式,使用wchar_t表示。
所有wchar_t*型別的字串(包括硬編碼在.h/.cpp裡的字串字面值),VC都自動採用UTF-16的編碼(字串字面值,literalstring,存在很多坑。
特別是char*型別的字面值,最終記憶體使用何種編碼方式完全取決於當前檔案的編碼方式。
也就是說當前檔案如果是GBK編碼的,那麼檔案裡char*str="中午",str指向的記憶體字串二進位制是使用GBK編碼的。
如果檔案編碼是UTF-8,那麼記憶體是使用UTF-8編碼。
所以為什麼一直要強調字串應該放在資原始檔裡,而不是硬編碼在.h/.cpp檔案裡!)。
UTF-16另外一個優勢就是常用字元都可以使用兩個個位元組表示,也就是一個wchar_t(這裡指Windows平臺)。
所以,在Windows平臺上,特別適合使用wchar_t來作為字串的儲存基型別。
一個wchar_t表示一個字元。
操作使用非常方便。
劣勢沒有統一的表示UTF-16編碼的字元型別。
C++98/03裡對wchar_t的定義是非常寬泛的。
這導致在Windows平臺上,wchar_t是2位元組的;在Unix-like系統上是4位元組的。
程式碼移植上,可能會遇到挑戰(我沒移植過,所以不確定會有什麼難度,以及難度有多大)。
即使最新的C++11裡已經定義除了char16_t表示UTF-16,MS的VS2013還不支援char16_t。
所以目前使用char16_t還不具移植性。
據我瞭解,UTF-16編碼和GBK編碼相比,還存在一個排序的劣勢。
也就是說,如果要按照漢語拼音的字母順序對漢字進行排序,GBK會得到正確的結果,而UTF-16就不行(暫時我還沒這種需求,所以我沒驗證過,不過好像我馬上就要與到這種需求了,到時候我再驗證下)。
UTF-16編碼字串的網路傳輸,要考慮大小端的問題。
另外網路傳輸中如果一個位元組資訊丟失,剩下的字串都無法正確解析。
統統亂碼。
另外,UTF-16並不是定長型別。
所以還是存在生僻字使用4個位元組編碼而不是2個位元組(但是Windows有例外。
在Windows(NT核心)平臺,從MSDN的各種表述來看,似乎一個wchar_t就是一個字元。
更多關於Windows平臺字元編碼的問題參考知乎回答和相關評論)。
UTF-32優勢這個優勢就明顯了,所有字元都是4位元組,fix-length。
一個wchar_t(Unix-like系統上)表示一個字元。
劣勢對於以英文為主的字串來說,空間消耗大。
面臨和上面UTF-16一樣的問題。
一致性,排序,網路傳輸,資料丟失後無法恢復。
char32_tVS2013還不支援(甚至VS14CPT也沒打算支援)。
總結UTF-8最適合用來作為字串網路傳輸的編碼格式。
UTF-16最適合當作本地字串編碼格式。
如果定義好了網路傳輸協議,那麼UTF-16也非常合適當作網路字串傳輸的編碼格式,特別是中文等遠東地區字符集。
比起UTF-8來說,節省一點點流量。
UTF-32沒什麼特殊癖好或者需求的話,暫時還用不上。
我個人覺得最佳實踐應該是:Linux上使用char,採用UTF-8編碼。
網路傳輸使用UTF-8編碼。
Windows上使用wchar_t/char16_t,採用UTF-16編碼。
將收到的網路資料統一從UTF-8轉碼到UTF-16。
在Windows上應該銘記沒有char/std::string這種型別的字元/字串,只有wchar_t/char16_t/std::wstring/std::u16string。
相關文章
int和Integer有什麼區別
2020-11-20
物件導向和麵向過程的區別
2020-11-21
物件導向
Mysql中MyISAM和InnoDB的區別
2020-11-16
MySQL
廣播與EventBus的區別
2020-11-17
EventBus
帶你瞭解Unicode和UTF-8編碼知識
2020-11-16
SQL中where和on的區別
2020-11-17
SQL
python中break和continue的區別
2020-11-17
Python
壓測的話,壓測客戶端多IP和一個IP多埠進行壓測有區別嗎?
2020-11-18
java.util.Date和java.sql.Date有什麼區別?
2020-11-18
JavaSQL
nodejs和js之間有什麼區別?
2020-11-20
Node.js
sessionStorage和localStorage的區別
2020-11-21
localStorage
jquery中$.get()提交和$.post()提交有區別嗎?
2020-11-21
jQuery
window.onload()函式和jQuery中的document.ready()有什麼區別?
2020-11-21
jQuery
教你理解let和var的區別
2020-11-22
Oracle中varchar2和nvarchar2區別
2020-11-22
Oracle
IDEA社群版(Community)和付費版(UItimate)的區別
2020-11-22
Unity
簡單工廠模式、工廠方法模式和抽象工廠模式有何區別?
2020-11-22
讓面試官心服口服:Thread.sleep、synchronized、LockSupport.park的執行緒阻塞有何區別?
2020-11-22
面試
offset與style區別
2020-11-22
最新文章
CMR:印度手機遊戲調查報告
大咖說·圖書分享|HaaS物聯網裝置雲端一體開發框架
話實踐,行實幹,成實事:“巡禮”數字化的中國大地
構建安全程式碼防止供應鏈攻擊
【推薦閱讀】超有用的漏洞掃描工具合集!
國密SM演算法有哪些?
為什麼伺服器選擇Linux系統
ApacheFlinkML2.1.0釋出公告
乾貨|作為前端開發者如何邁向獨立開發者
助力開發者,全方位解讀APISIX測試案例
得物資料庫中介軟體平臺“彩虹橋”演進之路
KubeSphere3.3.0離線安裝教程
延伸文章資訊
- 1「底層原理」Unicode與UTF-8的區別 - 每日頭條
UTF-8是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。UTF-8的編碼規則有 ...
- 2utf 8與unicode的區別 - w3c學習教程
utf 8與unicode的區別,1 unicode是一種字符集,而utf 8是一種編碼方式。unicode字符集既可以用utf 8編碼方式編成計算機能夠識別的二進位制數值,
- 3Unicode 與UTF-8 的關係?. Unicode… | by Roy Kwok - Medium
- 4Unicode 和UTF-8 有什么区别? - 知乎
举一个例子:It's 知乎日报. 你看到的unicode字符集是这样的编码表:. I 0049 t 0074 ' 0027 s 0073 0020 知77e5 乎4e4e 日65e5 报62a5...
- 5幫你搞清ASCII、Unicode和UTF-8區別,拿走不謝 - 人人焦點
幫你搞清ASCII、Unicode和UTF-8區別,拿走不謝. 2020-11-13 品位集結號. 首先說一下背景:由於計算機是美國人發明的,因此最早只有127個字母被編碼到計算機中,也就是 ...