UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx
上面的表格左邊是16進制表示的unicode內碼,最後一行的16進制數“7FFF FFFF”是utf8所能表示的內碼的最大值,換成10進制是這樣的一個數:2147483647(夠大吧:))[對不起,此文最初這兒寫錯了,已改正]。上面表格中右邊一列就是utf8的二進制格式,轉換規則可謂一目了然。我直接給出算法吧(js代碼):
function toUtf8(code)
{
var iByte=0;
var i=0;
result="";
while(code>0x7f)
{
iByte=code%0x40;
code=(code-iByte)/0x40;
result="%"+(iByte|0x80).toString(16).toUpperCase()+result;
i++;
}
prefix=[0x0,0xc0,0xe0,0xf0,0xf8,0xfc];
if(i>prefix.length)
{
i=5;
}
result=""+(code|prefix[i]).toString(16).toUpperCase()+result;
return result;
}
例如字符"漢"的unicode是6C49,把這個unicode字符表示為一個大整數,然後轉變成多字節編碼110110001001001:
觀察這個整數的二進制碼序列(110,110001,001001)
從後往前取
如果這個二進制序列只有後7位(小於128,也就是ascii字符)則直接取後7位二進制數形成一個utf8字符。
上面的字符“漢”二進制序列大於7位,所以取後6位(1001001),加10形成一個utf8字節(10 001001 ,16進制89)。
剩下的二進制序列(110,110001)從後向前取6位,加10形成一個utf8字節(10 110001,16進制B1)。
剩下的二進制序列(110)從後向前取6位,由於不足6位,將這個數和1110000相或,得到字符11100110,16進制E6
最後,就得到了utf8編碼,16進制表示為E6B189
【應用領域】
雖然這種標准算法大部分已經由開發工具提供商或者庫實現,但是我們依然會在某些時候需要自己實現這種算法:
某些浏覽器(ie5)不支持encodeURI函數,那麼使用ajax提交漢字有兩種方案:
漢字字符經escape轉變成形如"%uXXXX"的字符,服務端使用上述算法將u後面的unicode序號轉變成utf8字符
使用上面的算法結合escape直接在客戶端實現encodeURI功能(推薦使用這種方案)
實現json-rpc服務
json是javascript的對象直接量形式,其中字符串必須是unicode字符,漢字需要轉換成"\uXXXX"的形式。所以我們需要把服務端字符進行json轉變。對於php來說,現在有兩個開源項目JSON-PHP 和 PHP-JSON。
json-rpc是一種以json為數據格式的rpc協議,可以方便應用與ajax項目中,json-rpc.org是一個開源的實現。