世界上通用的編碼方式為unicode (萬國碼)
通過這種方式我們得到了一個統一的並且包含各種字符的編碼表,但是這種編碼方式有個極大的缺點:unicode的每個字符固定格式,如果我們存儲一個單字符的它會極大的浪費空間
於是人們發明了各種編碼規則utf-8,gbk...等
但這么多的編碼規則,就會出現這樣的情況:假如A使用utf-8編碼了一個文件,當B使用gbk去解釋這個文件時則會出現亂碼 (因此我們要統一好字符格式)
因此我們可以將utf-8 轉化為unicode再將unicode轉化為gbk
utf-8的編碼規則
1) 對於單字節的符號, 字節的第一位設為0, 后面7位為這個符號的unicode碼. 因此對於
英語字母, UTF-8編碼和ASCII碼是同樣的.
2) 對於n字節的符號(n>1), 第一個字節的前n位都設為1, 第n+1位設為0, 后面字節的前
兩位一律設為10. 剩下的沒有提及的二進制位, 所有為這個符號的unicode碼.
例如 以漢字嚴為例
已知"嚴"的unicode是4E25(1001110 00100101), 依據上表, 能夠發現4E25處在第三行的
范圍內(0000 0800 - 0000 FFFF), 因此"嚴"的UTF-8編碼須要三個字節, 即格式是
"1110xxxx 10xxxxxx 10xxxxxx". 然后, 從"嚴"的最后一個二進制位開始, 依次從后向前
填入格式中的x, 多出的位補0. 這樣就得到了, "嚴"的UTF-8編碼是 "11100100 10111000
10100101", 轉換成十六進制就是E4B8A5.
php實現utf-8轉為unicode
<?php $str = '嚴'; $name = iconv('UTF-8', 'UCS-2BE', $str); //php的內置函數 iconv 將utf-8的編碼轉為ucs(unicode)系列編碼 $len = strlen($str); $str = ''; for ($i = 0; $i < $len - 1; $i = $i + 2){ $c = $name[$i]; $c2 = $name[$i + 1]; //不懂為什么要取兩位 //ord函數 返回字符的ascii碼值 //base_convert 將一個進制數 轉化為另一個進制數 //str_pad 填充0 if (ord($c) > 0){ $str .= '\u'.base_convert(ord($c), 10, 16).str_pad(base_convert(ord($c2), 10, 16), 2, 0, STR_PAD_LEFT); } else { $str .= '\u'.str_pad(base_convert(ord($c2), 10, 16), 4, 0, STR_PAD_LEFT); } } echo $str;