2008年4月3日 星期四

[PHP]utf8轉big5之方法

最近寫程式會用到 utf8 轉 big5,本來想說用iconv就好了

不過我在使用iconv,將utf8轉big5時就出現一個問題,就是只要遇到utf8轉big5,沒有對應的big5碼的時候就有狀況了,原本以為就那個字沒出現,結果是當對應不到big5碼後它是以後的通通不見了,當然這下子就不妙了。

最後我只好一個字一個字轉,然後遇到沒有對應的碼就用"■"代替,雖然損失了效能,但是卻確保了正確性。

//逐字轉換utf8字串為big5
function utf8_2_big5($utf8_str) {
$i=0;
$len = strlen($utf8_str);
$big5_str="";
for ($i=0;$i<$len;$i++) {
$sbit = ord(substr($utf8_str,$i,1));
if ($sbit < 128) {
$big5_str.=substr($utf8_str,$i,1);
} else if($sbit > 191 && $sbit < 224) {
$new_word=iconv("UTF-8","Big5",substr($utf8_str,$i,2));
$big5_str.=($new_word=="")?"■":$new_word;
$i++;
} else if($sbit > 223 && $sbit < 240) {
$new_word=iconv("UTF-8","Big5",substr($utf8_str,$i,3));
$big5_str.=($new_word=="")?"■":$new_word;
$i+=2;
} else if($sbit > 239 && $sbit < 248) {
$new_word=iconv("UTF-8","Big5",substr($utf8_str,$i,4));
$big5_str.=($new_word=="")?"■":$new_word;
$i+=3;
}
}
return $big5_str;
}


BIG5 與 unicode 的轉碼程式測試


一、前言

為了試驗 iconv 轉碼的可信賴度,我們使用 MS-word 所提供的轉碼機制來和 iconv 轉碼的結果做比較。我們假設 MS-word 所提供的轉碼機制是可信賴的。


二、測試方法
我們將測試分成兩個部分執行,一、將 big5 編碼的資料轉成 utf8 ,並驗證 轉出來的結果。二、將 utf8 編碼的資料轉成 big5 ,並驗證結果。步驟如下:

1. 將 big5 編碼的資料轉成 utf8
2. 比較 iconv 和 MS-Word 轉出來的結果
3. 將 utf8 編碼的資料轉成 big5
4. 比較 iconv 和 MS-Word 轉出來的結果


三、測試平台
下列為本次測試使用軟體的版本及作業系統平台:

* iconv:
o 作業系統:Redhat Linux 7.3,
o 程式版本:glibc 2.2.5 版的工具
* MS-word:
o 作業系統:MS Windows XP,
o 程式版本:MS office-XP


四、產生測試資料

為了測試到 big5 碼的每一個字元,所以必須寫一個程式產生 big5 碼的每一個字元。下列表格為 big5 碼的編碼範圍(參考倚天中文系統手冊),總共是 19,782 個字元。但其中包含了 63 個控制碼及 5809 個使用者造字碼,必須扣除,所以實際的字碼共有 13910 個字元。
BIG5 碼的範圍: (計 19,782 個)
高位元組: A1~FE, 8E~A0, 81~8D (計 126 個)
低位元組: 40~7E, A1~FE (計 157 個)
控制碼的範圍: (計 63 個)
控制碼: A3C0~A3E0 (計 33 個)
保留之控制碼: A3E1~A3FE (計 30 個)
使用者造字(USRFONT):(計 5,809 個)
第一段: FA40~FEFE (計 785 個)
第二段: 8E40~A0FE (計 2,983 個)
第三段: 8140~8DFE (計 2,041 個)

big5.py為 big5 碼產生程式,執行的結果會輸出所有的 big5 字元,輸出的格式為每一行一個字元。下列為使用範例:

$ big5.py > big5.txt


五、BIG5 碼轉 UTF8 碼測試

產生了測試資料之後,首先測試 BIG5 碼轉 UTF8 碼。

*
使用 iconv 將 BIG5 碼轉成 UTF8

iconv 以 -f 參數指定輸入資料的編碼,-t 參數指定輸出資料的編碼。轉碼指令如下:

$ iconv -f big5 -t utf8 big5.txt > utf8-iconv.txt


*
使用 MS Word 將 BIG5 碼轉成 UTF8

使用 MS-Word 轉碼要先開啟 Word 將檔案載入,再將資料另外存成其他編碼格式。詳細步驟如下:
1. 執行 MS-Word
2. 使用[檔案]->[開啟舊檔]選項載入 big5.txt 檔
3. MS-Word 要求使用者選擇輸入檔的編碼,這時要選擇 big5 編碼
4. 使用[檔案]->[另存新檔]將資料存成其他檔名,例如: utf8-msword.txt
5. MS-Word 要求使用者選擇輸出檔的編碼,這時要選擇 utf8 編碼



*
比較 iconv 和 MS Word 轉碼出來的結果

當 iconv 和 MS-word 個別產生一份轉碼的結果之後,再來就是比較兩分結果的差異。在比較之前,必須先將 MS Word 的輸出檔格式做一點調整。因為在 Windows 平台上的程式會在換行字元再插入'\r'字元,必須先將每一行的'\r'字元刪除。下 列為使用 tr 指令刪除 '\r' 字元的方法:

$ tr <> utf8-msword-1.txt

下列為比較兩個輸出檔差異的方法:

$ diff utf8-iconv.txt utf8-msword-1.txt

結果兩個檔案的內容完全一樣,代表 iconv 和 MS-Word 將 BIG5 將成 UTF8 時,對應表完全相同。


六、UTF8 碼轉 BIG5 碼測試

測試完 BIG5 轉 UTF8 之後,接著反過來測 UTF8 轉 BIG5。測試資料直接使用上一節轉碼之後的結果。由於 utf8-iconv.txt 和 utf8-msword-1.txt 的內容一樣,所以任取一個檔即可。為了測試方便,將該測試資料改名為 utf8.txt。

*
使用 iconv 將 UTF8 碼轉成 BIG5
iconv 以 -f 參數指定輸入資料的編碼,-t 參數指定輸出資料的編碼。轉碼指令如下:

$ iconv -f utf8 -t big5 utf8.txt > big5-iconv.txt



*
使用 MS Word 將 UTF8 碼轉成 BIG5

使用 MS-Word 轉碼要先開啟 Word 將檔案載入,再將資料另外存成其他編碼格式。詳細步驟如下:
1. 執行 MS-Word
2. 使用[檔案]->[開啟舊檔]選項載入 utf8.txt 檔
3. MS-Word 要求使用者選擇輸入檔的編碼,這時要選擇 utf8 編碼
4. 使用[檔案]->[另存新檔]將資料存成其他檔名,例如: big5-msword.txt
5. MS-Word 要求使用者選擇輸出檔的編碼,這時要選擇 big5 編碼



*
比較 iconv 和 MS Word 轉碼出來的結果
先刪除 big5-msword.txt 的 '\r' 字元,理由同上一節之說明。

$ tr <> big5-msword-1.txt

比較兩個檔案的差異:

$ diff big5-iconv.txt big5-msword-1.txt

結果有 15 個字元相異,這 15 個相異的字元全都是符號,雖說是相異字元 (內碼不同),外形幾乎完全相同。也就是說在UTF8轉BIG5的正確性上來說, iconv 和 MS-word 的結果幾乎完全相同,除了幾個疑似重複的符號之外。


七、結論

本測試分成兩個部分,一為 BIG5 轉 UTF8 測試,二為 UTF8 轉 BIG5 測試。 在 BIG5 轉 UTF8 部分, iconv 轉出來的結果和 MS-Word 轉出來的結果完全一樣。 而在 UTF8 轉 BIG5 部分,則只有 15 個字元不同。而這 15 個字元大部分全都是畫格線符號,符號的外形看不出有何差異,應該是 BIG5 碼本身重複收錄的字元。 除此之外, iconv 和 MS-Word 的轉碼結果沒有其他差異。

【下列文章您可能也有興趣】

沒有留言: