為什麼 UTF 8 編碼比 UTF 16 編碼應用更廣泛?

時間 2021-05-05 17:38:33

1樓:不世玄奇

■無限變長字元編碼方案

【目的】

無限變長編碼,不浪費儲存空間,一次掃瞄就能識別字元,亂碼不會擴散。

【基礎】

字元編碼由位元組組成,乙個位元組為8個二進位制位,理論上可表示2的8次方個字元。

【方案】

0開頭的編碼,當其前乙個編碼以0開頭時為ASCLL碼;當其前乙個編碼為1開頭時為變長編碼尾碼。注意:有個0開頭的編碼不能作為變長編碼尾碼,那就是檔案開頭標誌編碼。

1開頭的為變長編碼,其會一直向後掃瞄,直到遇到以0開頭的編碼時以其作為尾碼並標誌字元結束,理論上編碼可以無限長,且只需掃瞄一遍就能識別出字元。

【掃瞄】

掃瞄到檔案開頭,然後遇到0開頭的就視為ASCLL,遇到1開頭就繼續掃瞄,直到遇到0開頭的編碼時將其作為變長編碼尾碼,然後遇到1開頭就繼續掃瞄,直到遇到0開頭的編碼時將其作為變長編碼尾碼,然後遇到0開頭的就視為ASCLL……

【錯碼】

當傳輸過程中乙個編碼出錯時:

原字元會變成另乙個字元,錯誤僅限原字元。

當傳輸過程中缺失乙個編碼時:

若這個缺失的編碼以1開頭,則原字元將變成少乙個位元組的新字元,錯誤僅限原字元。

若這個缺失的編碼以0開頭,則原字元後那個字元會被連線到原字元編碼之後合二為一變成乙個新的字元,錯誤僅限原字元及其後那個字元。

2樓:暮無井見鈴

我猜這與網際網路的普及有關。至少在網際網路上 UTF-8 是一種相當不錯的交流格式。

網頁中 ASCII 字元的部分是相當大的,大多數場合用 UTF-8 一般比 UTF-16 更節省空間。決定這點的不是內容,而是 HTML 這種形式。另外就是 UTF-8 無位元組序問題在網路上也有優勢。

如果要讓 UTF-16 佔優勢的話,這個網頁的內容應該主要是特定範圍字元的文字,而且格式上的標記相當少。目前即使在中日韓,符合這種要求的網頁也不算多吧。

至於 C 傳統的 char* 介面,我猜影響並不關鍵,畢竟也有內部字串欽定 UTF-16 的流行語言。

3樓:不減肥成功不改名

補充一下,UTF 32 也不想理想中那麼方便索引,主要是 emoji 的鍋,舉兩個例子:

一、Emoji 裡面的國旗其實由兩個字元組成,稱為 region indicator,每個字元是乙個 region indicator symbol letter,從 A 到 Z,U+1F1E6 到 U+1F1FF。比如說法國國旗就是用 FR 的對應 region indicator symbol letter 來表示的。Swift 的 String 自稱有較好的 Unicode 支援,但對這樣的字元的長度目前給的還是 2(Unicode 8.

0 標準),而實際上 Unicode 9.0 已經要求把它們看作乙個字元了。

二、為了政治正確,人們引入了帶膚色的 emoji 表情,它們是由普通表情和乙個代表顏色的 emoji 字元組成。

於是乎,如果寫編輯器的話,不管怎麼樣都要 O(n) 來計算可見字元的長度的(這還沒有考慮韓語那種三個字元疊成乙個字元的情況),所以前端們很可憐的。

4樓:

1,utf 編碼方式的設計初衷主要就是節省,utf8 因為相容 ascii,可以使用乙個位元組表示英語世界常用字元,比較省空間和頻寬。utf16 就比較尷尬,因為使用了寬字元,對英語世界的使用者來說,很可能不但不節省還浪費空間和頻寬。至於中文世界嘛,用 utf8 其實有點浪費資源,用 utf8 主要是軟體棧的原因。

很多軟體因為是英語世界的人開發的,對 utf8 支援的最好。

2,utf16 因為使用兩個位元組為單位,所以分大尾和小尾,即 utf16 be 和 utf16 le。這個東西有點討厭,很多人其實並不知道 utf16 有兩種,他們也搞不清楚自己把資料存成了 be 還是 le。要麼你寫程式的時候相容掉,要麼就要求使用者分清楚大小尾。

問題是不寫程式的人誰會關注這個?

3,對於程式設計來說,最友好的編碼是 utf32。由於 utf32 表示任何字元都用 4 位元組,讀到記憶體中是個均勻的整形陣列,於是我們可以很方便地隨機訪問任何乙個字元。utf8 就不行,你想訪問乙個字串中的第 n 個字元,utf32 直接偏移 n 個整形距離即可,utf8 得從第乙個位元組乙個字乙個字地往後蹦,非常蛋疼。

4,所以最理想的文書處理方式是用 utf8 儲存和傳輸,程式讀到記憶體裡轉為 utf32 處理。

5樓:

因為對老美來說,UTF-8省錢啊!

乙個英文的字元用UTF-8只要乙個位元組,用UTF-16就是兩個位元組。新增的那個0x00對他們來說毫無用處呀!他們接觸到的文字資訊99.

9999%都只是英文的,幹嘛要付出多一倍的儲存/傳輸的代價編碼一堆0呢?相對ASCII,UTF-8既不給他們增加成本,又能在完美支援多語言,自然是理所當然的選擇了。

面對這樣的既成事實,中文只能在一邊去哭了……

6樓:林建入

UTF-16 能表示的字元數有 6 萬多,看起來很多,但是實際上目前 Unicode 5.0 收錄的字元已經達到 99024 個字元,早已超過 UTF-16 的儲存範圍;這直接導致 UTF-16 地位頗為尷尬——如果誰還在想著只要使用 UTF-16 就可以高枕無憂的話,恐怕要失望了

UTF-16 存在大小端位元組序問題,這個問題在進行資訊交換時特別突出——如果位元組序未協商好,將導致亂碼;如果協商好,但是雙方乙個採用大端乙個採用小端,則必然有一方要進行大小端轉換,效能損失不可避免(大小端問題其實不像看起來那麼簡單,有時會涉及硬體、作業系統、上層軟體多個層次,可能會進行多次轉換)

另外,容錯性低有時候也是一大問題——區域性的位元組錯誤,特別是丟失或增加可能導致所有後續字元全部錯亂,錯亂後要想恢復,可能很簡單,也可能會非常困難。(這一點在日常生活裡大家感覺似乎無關緊要,但是在很多特殊環境下卻是巨大的缺陷)

目前支撐我們繼續使用 UTF-16 的理由主要是考慮到它是雙位元組的,在計算字串長度、執行索引操作時速度很快。當然這些優點 UTF-32 都具有,但很多人畢竟還是覺得 UTF-32 太佔空間了。

反過來 UTF-8 也不完美,也存在一些問題:

文化上的不平衡——對於歐美地區一些以英語為母語的國家 UTF-8 簡直是太棒了,因為它和 ASCII 一樣,乙個字元只佔乙個位元組,沒有任何額外的儲存負擔;但是對於中日韓等國家來說,UTF-8 實在是太冗餘,乙個字元竟然要占用 3 個位元組,儲存和傳輸的效率不但沒有提公升,反而下降了。所以歐美人民常常毫不猶豫的採用 UTF-8,而我們卻老是要猶豫一會兒

變長位元組表示帶來的效率問題——大家對 UTF-8 疑慮重重的乙個問題就是在於其因為是變長位元組表示,因此無論是計算字元數,還是執行索引操作效率都不高。為了解決這個問題,常常會考慮把 UTF-8 先轉換為 UTF-16 或者 UTF-32 後再操作,操作完畢後再轉換回去。而這顯然是一種效能負擔。

當然,UTF-8 的優點也不能忘了:

字元空間足夠大,未來 Unicode 新標準收錄更多字元,UTF-8 也能妥妥的相容,因此不會再出現 UTF-16 那樣的尷尬

不存在大小端位元組序問題,資訊交換時非常便捷

容錯性高,區域性的位元組錯誤(丟失、增加、改變)不會導致連鎖性的錯誤,因為 UTF-8 的字元邊界很容易檢測出來,這是乙個巨大的優點(正是為了實現這一點,咱們中日韓人民不得不忍受 3 位元組 1 個字元的苦日子)

那麼到底該如何選擇呢?

因為無論是 UTF-8 和 UTF-16/32 都各有優缺點,因此選擇的時候應當立足於實際的應用場景。例如在我的習慣中,儲存在磁碟上或進行網路交換時都會採用 UTF-8,而在程式內部進行處理時則轉換為 UTF-16/32。對於大多數簡單的程式來說,這樣做既可以保證資訊交換時容易實現相互相容,同時在內部處理時會比較簡單,效能也還算不錯。

(基本上只要你的程式不是 I/O 密集型的都可以這麼幹,當然這只是我粗淺的認識範圍內的經驗,很可能會被無情的反駁)

稍微再展開那麼一點點……

在一些特殊的領域,字元編碼的選擇會成為乙個很關鍵的問題。特別是一些高效能網路處理程式裡更是如此。這時採用一些特殊的設計技巧,可以緩解效能和字符集選擇之間的矛盾。

例如對於內容檢測/過濾系統,需要面對任何可能的字元編碼,這時如果還採用把各種不同的編碼都轉換為同一種編碼後再處理的方案,那麼效能下降將會很顯著。而如果採用多字元編碼支援的有限狀態機方案,則既能夠無需轉換編碼,同時又能夠以極高的效能進行處理。當然如何從規則列表生成有限狀態機,如何使得有限狀態機支援多編碼,以及這將帶來哪些限制,已經又成了另外的問題了。

我就是隨便這麼一展開而已

7樓:

1. 相容 ASCII

2. 能適應許多 C 庫中的 \0 結尾慣例3. 沒有位元組序問題

4. 良好的多語種支援(相對 GBK 等跟語種繫結的編碼方式)5. 以英文和西文符號比較多的場景下(例如 HTML/XML),編碼較短

8樓:

因為現在的世界仍然是歐美人主導的世界,大部分的資訊仍然是以ascii碼形式存在的。utf8儲存ascii碼資訊很明顯更有效率。等哪天網際網路上的資訊cjk佔絕大多數的時候,就是utf16大行其道的時候。

中文字元Unicode和UTF 8的編碼為什麼不能一樣?

Stony Wang Unicode是乙個編號的定義,UTF 8 是一種序列化格式約定,用於儲存或者傳輸。出現各種UTF 編碼是出於 相容效率 等各種目的的需要。比如UTF 8 相容ASCII的前128個符號,所有儲存為ASCII的文件用UTF 8來處理毫無障礙。對於大量東亞字元文件,UTF 16儲...

簡單來說,utf8是什麼?

三一斜狩 簡單來說,是一種編碼規則。將兩個位元組為乙個單位的 0x0000 0x10FFFF範圍內的數值,以8bits 1byte 為單位,進行編碼的規則。其編碼原則是節約空間。比如可能某個數值是占用兩個位元組,經過utf8編碼,會變成乙個位元組。但是其實更多的兩個位元組,可能編碼成了3個位元組或者...

Java 為什麼使用 UTF 16 而不是更節省記憶體的 UTF 8?

117B3CC5374B962A echo n 對於記憶體非常不友好 utf 8.txt cat utf 8.txt iconv t utf 16 utf 16.txt file utf txt utf 8.txt UTF 8 Unicode text,with no line terminator...