close

單純轉換

我們大致上會需要以下幾種 encoding 之間的相互轉換。

  • BIG5
  • GB2312
  • UTF-8
  • Unicode
  • wchar_t

其中,Unicode 指 UCS2-LE、UCS2-BE、UCS4-LE 或 UCS4-BE 等 encoding,而 wchar_t 則視平台而定。純粹的 encoding 互轉的話,由於 Unicode 號稱能納萬物,所以建議的轉換程序如下:

  • BIG5 <-> Unicode/UTF-8
  • BIG5 -> Unicode/UTF-8 -> GB2312
  • GB2312 <-> Unicode/UTF-8
  • GB2312 -> Unicode/UTF-8 -> BIG5

而若以「外部檔案用與平台無關的 encoding 如 BIG5、GB2312 或 UTF-8,內部程式使用 wchar_t 執行演算法」的準則來看的話,我們會需要以下幾種 encoding 轉換:

  • BIG5 <-> wchar_t
  • GB2313 <-> wchar_t
  • UTF-8 <-> wchar_t

進階轉換

另外,除了純粹的 encoding 轉換之外,也許有時還會需要更進一步的轉換機制:

  • 處理非一對一對應:好比在繁簡體中文之間,有所謂一對多的困擾,一個簡體字,可能對應到多個繁體字。若有能夠依據前後文決定如何選取一對多的多個字中的哪一個字,這樣子的轉換會比單純的 encoding 轉換還要來得精準。
  • 詞彙轉換:能轉換同義異形的兩岸詞彙用語。

轉換工具:libiconv

在 UNIX 上,首推 iconv,這是 libiconv 的 command-line wrapper,Linux 及 FreeBSD 的 kernel 也是用 libiconv 做 encoding 轉換的。依據 platform 的不同,libiconv 能夠支援的 encoding 也會有所不同,只要在該平台上的 libiconv 有支援的任兩個 encoding,libiconv 都能互相轉換。libiconv 亦有 Windows porting,可至 GnuWin32 網站抓。libiconv 轉換的機制是:

  1. 如果可以一對一轉換 (i.e. 有 table 支援),就做一對一轉換
  2. 否則,便先轉換成某一種 unicode,再轉成欲轉換的 encoding

因此,要使用 libiconv 在各個平台上,理論上我們只需要注意該平台的 libiconv 有支援哪些 encoding 即可。以下是我使用 libiconv 曾碰過的一些問題:

  1. 在 FreeBSD 4 的 libiconv 沒有 wchar_t 支援,這是由於 FreeBSD 4 沒有正式支援 wchar_t 的緣故。在 FreeBSD 5 上就有正式支援 wchar_t 了。
  2. 在 Linux 上,RedHat 7、跟 RedHat 9,印象中都有 wchar_t 支援,在 Linux 上使用 libiconv 對我們常會用到的 encoding 間做轉換,沒有問題。
  3. 在 Windows 上的 libiconv,亦沒有 wchar_t 支援[1]
  4. libiconv 不認得七個 BIG5 擴充字:碁, 銹, 裏(請改用'裡'), 墻, 恒, 粧, 嫺,無法將之轉換成對應的 UTF-8;但 Windows API 認得且可以轉換成 UTF-8。

轉換工具:ConvertZ

在 Windows 上,兩岸間最有名的轉碼工具便是 ConvertZ。ConvertZ 所列出的那些轉碼選項,只要在安裝 Windows 時有安裝好該 encoding 的 windows 組件,ConvertZ 便有辦法作轉換。另外,ConvertZ 亦有針對兩岸語言的不同,另外做一些一對多及詞彙轉換的工作。同時,ConvertZ 也有多種使用方法,方便各種應用情境。詳細使用說明請見 ConvertZ 網頁。

轉換工具:Windows API

大致上使用兩個 API:MultiByteToWideChar() 跟 WideCharToMultiByte()。這兩個 APIs 能在 wide-character 與 multi-byte character 之間作轉換,其中,CodePage 這個參數指的是 multi-byte character 的 encoding,常用的有兩種:

  • CP_ACP:ANSI code page,在 Windows API 裡,這指的是 Windows 安裝平台,好比繁體中文的 CP_ACP 預設是 BIG5。不過,在使用上,需搭配 C locale 一起用,也就是說,CP_ACP 其實是跟著 setlocale() 所設定的 locale 走的。
  • CP_UTF8:指定轉換的 multi-byte character 的 encoding 為 UTF-8。在 Windows 上,我們可以藉由指定 CP_UTF8,在 wchar_t 與 utf-8 之間作轉換。

詳細參數、用法請見 MSDN


2007-01-11 補充Joel 的這篇《The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)[2]寫的不錯,講 encoding/unicode 講的很清楚。

 


  1. 2008-01-03 新增:這是 libiconv 版本的問題,請見《Right libiconv version for Windows》。 
  2. 中譯:《每個軟體開發者都絕對一定要會的Unicode及字元集必備知識(沒有藉口!)》。

資料來源:http://www.jeffhung.net/blog/articles/jeffhung/261/

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 白努力電腦日記 的頭像
    白努力電腦日記

    包包的雲端語意小說

    白努力電腦日記 發表在 痞客邦 留言(0) 人氣()