當前位置:才華齋>計算機>php語言>

談談php中的unicode和utf8編碼

php語言 閱讀(2.16W)

本文給大家深入討論了unicode和utf8這兩種編碼的關係,理解好了會發現網上一些舊的東西,是嚴重多餘兼過期的,因為從utf-8流行開始到現在,早已經由原來六位元組可變編碼到實際完全居於unicode(UCS-2)的穩定階段。

談談php中的unicode和utf8編碼

  重新認識unicode和utf8編碼

直到今天,準確的說是剛才,我才知道UTF-8編碼和Unicode編碼是不一樣的,是有區別的囧

他們之間是有一定的聯絡的,看看他們的區別:

UTF-8的長度是不一定的,有可能是1、2、3位元組

Unicode長度一定,2個位元組(USC-2)

UTF-8可以和Unicode互相轉換

unicode和utf8的關係

Unicode(16進位制)

UTF-8(二進位制)

0000 - 007F 0xxxxxxx

0080 - 07FF 110xxxxx 10xxxxxx

0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

上面的表格有2個意思,第一個顯而易見就是說Unicode和UTF-8字元範圍的對應,還有一個可以看出Unicode怎麼和UTF-8互相轉換:

先說UTF-8到Unicode的轉換

UTF-8編碼的二進位制和上面的3種格式進行匹配,匹配到之後去掉固定位(表格中的非x位置),然後從右到左每8位一組,不夠8位左邊不領,湊夠2個位元組16 bits,這16 bits所表示的就是UTF-8對應的Unicode編碼,看看下面幾個例子:

上面圖片中的文字編碼格式為UTF-8,可以用WinHex看到其16進製表示

複製程式碼 程式碼如下:

字元 => UTF-8 => UTF-8二進位制=> 去掉固定位置湊夠16位的二進位制 => 16進位制

漢 => E6B189 => 11100110 10110001 10001001 => 01101100 01001001 => 6C49

  字 => E5AD97 => 11100101 10101101 10010111 => 01011011 01010111 => 5B57

  #下面是在chrome命令列下面執行的結果

'u6C49'

"漢"

'u5B57'

"字"

#到這裡的'話,從UTF-8轉換到Unicode已經是一件非常容易的事了,看看轉換的虛擬碼

讀取一個位元組,11100110

判斷該UTF-8字元的格式,屬於第三種,3個位元組

繼續讀取2個位元組得到 11100101 10101101 10010111

按照格式去掉固定位 1011011 01010111

不夠16位,左邊補零 01011011 01010111 => 5B57

再看看從Unicode到UTF-8的轉換

複製程式碼 程式碼如下:

5B57

獲取5B57所在的Unicode範圍,0800 <= 5B57 <= FFFF,得知5B57的UTF-8有三個位元組,形式為1110xxxx 10xxxxxx 10xxxxxx

獲取5B57的二進位制編碼 101101101010111

用上一步驟的二進位制編碼從右至左拼接UTF-8編碼 11100101 10101101 10010111

說說問題

再說說今天這個問題的起因,從前端輸入很多單詞,UTF-8格式每個詞最多30個位元組,因此會在前端和後臺分別做驗證,javascript用的是Unicode編碼,後端程式用的是UTF-8編碼,現在的解決辦法是這樣

前端

?

1

2

3

4