當我們說 UTF-8 和 Unicode 的時候到底在說什麼?

本文參考:
字符編碼筆記:ASCII,Unicode 和 UTF-8

這個問題的來源於最近 Python 語言的學習中。在 Python3 中,使用 Unicode 對字符串進行編碼,這使 Python3 成爲一個多語言的語言。同樣的,在 Python 中,支持 ord(), chr() 這樣的函數對字符串和字符串的 ASCII 十進制值。

在實際的運用過程中,PHP 也包含類似的函數,但是對相同的中文字符,兩個函數輸出的結果卻不同,於是有了對 UnicodeUTF-8 的疑問和探索

字符編碼的由來

在計算機內部只能識別 二進制 的數據,爲了讓每個英文單詞在計算機內部能夠被表示出來,美國製定了一套字符編碼,表示 英文字符與二進制位 之間的關係,也就是說,每一個 英文字符 都對應了一個 二進制的編碼,這相當於有一個 集合
而制定這個 “表” 必須要有一定的規則,所以美國製定了 ASCII 碼,規定用 一個字節(8bit) 來表示 128 個英文字符。比如 A 就是 65,二進制爲 0100 0001。這 128 個字符只能佔 7 個位,最前面的一個位默認都爲 0

ASCII 碼的擴展

128 個字符對於英文編碼來說夠用了,但是對於世界上其他國家的很多語言來說是遠遠不夠的。在計算機慢慢普及的過程中,歐洲一些國家漸漸的字符漸漸被編入 ASCII 碼中,利用原 ASCII 編碼的最高位,越來越多的國家漸漸擴展出了自己的編碼,這樣就帶來了新的問題

當 256 個字符被佔完,也就是 8 個 bit 位被用完的時候,相同的十進制編碼在不同的國家中可能會存在衝突,被編碼成不同的字符。對於亞洲國家來說,256 個字符就更不夠用了

Unicode 產生

隨着編碼方式越來越多,同一個十進制或二進制會被編譯成不同的符號。爲了解決這個問題,人們意識到,要用一個新的編碼,將世界上所有的字符全部編入其中,這樣,全世界統一使用這個編碼,就不會產生衝突和亂碼了

這個 集合 就是 Unicode,它將世界上所有的字符都拿出其中並給出對應的二進制,十進制,十六進制值

注意,Unicode, ASCII 都只是一種編碼標準,它規定的是 某某字符應該是用 XXX 值表示 這種標準,而沒有指定一種具體的行爲去實現從 某某字符轉換到二進制編碼 這樣一種過程

比如,A 用兩個字節來存儲 Unicode 編碼的二進制表示,B 用三個字節來存儲 Unicode 編碼的二進制表示,在計算機中,就需要去根據不同的 規則 來對內容進行翻譯和解釋

UTF-8

隨着互聯網的興起,計算機與網絡,計算機與計算機之間的通訊急需一種統一的 編碼方式 來編譯和解釋 Unicode 編碼

這種 編碼方式 就是我們現在使用最廣泛的 UTF-8,
所以,UTF-8 是 Unicode 編碼的一種具體實現,它規定了字符轉換到二進制編碼的一系列規則

UTF-8 最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度

UTF-8 的編碼規則有兩個:

  • 對於單字節的符號,字節的第一位設爲 0,後面 7 位爲這個符號的 Unicode 碼

  • 對於 n 字節的符號(n > 1),第一個字節的前 n 位都設爲1,第 n + 1 位設爲 0,後面字節的前兩位一律設爲 10。剩下的沒有提及的二進制位,全部爲這個符號的 Unicode 碼

PHP 中的 ord() 和 Python 中的 ord() 區別

php 中的 ord 函數,轉換字符串第一個字節爲 0-255 之間的值,也就是說,php 的 ord 函數在作用於中文字符串的時候,並不會把所有的字符串都轉化爲十進制的 ASCII 值,只會轉換第一個字節的字符爲 ASCII

python 中的 ord 函數,給定一個 Unicode 編碼的字符串,返回一個十進制整數,所以 python 中的 ord 函數如果處理的字符串是 Unicode 編碼的,那麼將返回完整的十進制數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章