UTF-8就是Unicode Transformation Format-8,是Unicode的一種變換編碼格式。本文介紹了UTF-8轉換爲Unicode編碼的方法,給出了在J2ME環境下的實現。
UTF-8就是Unicode Transformation Format-8,是Unicode的一種變換編碼格式。
UTF-8 有以下特性:
UCS 字符 U+0000 到 U+007F (ASCII) 被編碼爲字節 0x00 到 0x7F (ASCII 兼容). 這意味着只包含 7 位 ASCII 字符的文件在 ASCII 和 UTF-8 兩種編碼方式下是一樣的.
所有 >U+007F 的 UCS 字符被編碼爲一個多個字節的串, 每個字節都有標記位集. 因此, ASCII 字節 (0x00-0x7F) 不可能作爲任何其他字符的一部分.
表示非 ASCII 字符的多字節串的第一個字節總是在 0xC0 到 0xFD 的範圍裏, 並指出這個字符包含多少個字節. 多字節串的其餘字節都在 0x80 到 0xBF 範圍裏. 這使得重新同步非常容易, 並使編碼無國界, 且很少受丟失字節的影響.
可以編入所有可能的 231個 UCS 代碼
UTF-8 編碼字符理論上可以最多到 6 個字節長, 然而 16 位 BMP 字符最多只用到 3 字節長.
Bigendian UCS-4 字節串的排列順序是預定的.
字節 0xFE 和 0xFF 在 UTF-8 編碼中從未用到.
下列字節串用來表示一個字符. 用到哪個串取決於該字符在 Unicode 中的序號.
U-00000000 - U-0000007F:
0xxxxxxx
U-00000080 - U-000007FF:
110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF:
1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF:
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF:
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF:
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
從上表還可以看出,UTF-8每個編碼字符都不可能以“10”開頭,“10”是以連接符的形式出現在後面的編碼字節開頭。因此UTF-8編碼在存儲和傳輸時是不容易出錯的。
下面是UTF-8到Unicode的編碼轉換代碼(J2ME環境下的實現):UTFC2UniC方法包含了編碼轉換邏輯。
/**
* 將UTF-8字節數據轉化爲Unicode字符串
* @param utf_data byte[] - UTF-8編碼字節數組
* @param len int - 字節數組長度
* @return String - 變換後的Unicode編碼字符串
*/
public static String UTF2Uni(byte[] utf_data, int len)
{
StringBuffer unis = new StringBuffer();
char unic = 0;
int ptr = 0;
int cntBits = 0;
for(;ptr < len;)
{
cntBits = getCntBits(utf_data[ptr]);
if(cntBits == -1)
{
++ptr;
continue;
}
else
if(cntBits == 0)
{
unic = UTFC2UniC(utf_data, ptr, cntBits);
++ptr;
}
else
{
unic = UTFC2UniC(utf_data, ptr, cntBits);
ptr += cntBits;
}
unis.append(unic);
}
return unis.toString();
}
/**
* 將指定的UTF-8字節組合成一個Unicode編碼字符
* @param utf byte[] - UTF-8字節數組
* @param sptr int - 編碼字節起始位置
* @param cntBits int - 編碼字節數
* @return char - 變換後的Unicode字符
*/
public static char UTFC2UniC(byte[] utf, int sptr, int cntBits)
{
/*
Unicode <-> UTF-8
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
int uniC = 0; // represent the unicode char
byte firstByte = utf[sptr];
int ptr = 0; // pointer 0 ~ 15
// resolve single byte UTF-8 encoding char
if(cntBits == 0)
return (char) firstByte;
// resolve the first byte
firstByte &= (1 << (7 - cntBits)) - 1;
// resolve multiple bytes UTF-8 encoding char(except the first byte)
for(int i = sptr + cntBits - 1; i > sptr; --i)
{
byte utfb = utf[i];
uniC |= (utfb & 0x3f) << ptr;
ptr += 6;
}
uniC |= firstByte << ptr;
return (char)uniC;
}
// 根據給定字節計算UTF-8編碼的一個字符所佔字節數
// UTF-8規則定義,字節標記只能爲0或2~6
private static int getCntBits(byte b)
{
int cnt = 0;
if (b == 0) return -1;
for(int i = 7; i >= 0; --i)
{
if (((b >> i) & 0x1) == 1)
++cnt;
else
break;
}
return (cnt > 6 || cnt == 1) ? -1 : cnt;
}
參考資料:
《UTF-8 and Unicode FAQ》—— http://[url]www.linuxforum.net/books/UTF-8-Unicode.html[/url]
unicode編碼原理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
Linux基本操作命令
wbzjacky
2019-02-24 13:12:38
真實的模擬***綜合實驗
wbzjacky
2019-02-24 13:12:37
三層交換機的HSRP、vlan、端口聚合
wbzjacky
2019-02-24 13:12:37
HSRP和二層交換機的端口聚合、vlan
wbzjacky
2019-02-24 13:12:37
如果同事暗中傷害你,應該怎麼辦?
這個饅頭有餡
2019-02-24 13:59:08
職場中,抱怨越多的員工,越被領導瞧不起!
這個饅頭有餡
2019-02-24 13:59:08
老程序員被裁,應屆生卻能月薪 1.3 萬?這你能忍?
前端高達
2019-02-24 13:48:04
遇到到處蹭吃卻從不請客吃飯的主怎麼辦?
樑軍年
2019-02-24 13:26:35
高標準機房綜合配線安裝
wbzjacky
2019-02-24 13:12:38
IPsec ***實驗
wbzjacky
2019-02-24 13:12:37
CISCO路由AAA的Easy ***
wbzjacky
2019-02-24 13:12:37
CISCO訪問控制列表 企業網絡管理的必殺技
wbzjacky
2019-02-24 13:12:37
24小時熱門文章
-
再談23種設計模式(3):行爲型模式(學習筆記)
-
Power Automate Desktop 安裝完,登錄後老是提示one driver 錯誤
-
微前端學習筆記(4):從微前端到微模塊之EMP與hel-micro方案探索
-
微前端學習筆記(1):微前端總體架構概述,從微服務發微
-
985 碩士程序員,空窗 4 個月沒有 Offer!
-
一文搞懂 Spring 循環依賴
-
賽博鬥地主——使用大語言模型扮演Agent智能體玩牌類遊戲。
-
VScode右鍵打開(添加到右鍵)
-
記一次 .NET某工控視覺自動化系統 卡死分析
-
WindowsServer--SQL Server搭建主從同步實現讀寫分離 - 事務性分發