[C#][編碼] Big5 Encoder 支援日文編碼
最近在寫Telnet瀏覽器玩玩看,原本終於處理好ANSI的雙色字問題,正要開始寫互動介面才想到我還沒有測試過日文編碼能不能解讀。根據我的記憶Big5的系統內建只有中文必須裝了別的編碼包之後才能把自訂區的字碼變成日文,果然一次測試我就看到一堆問號,這時候我只好開始尋求解決方案。首先是Google到一篇msdn論壇的文章是安裝Unicode補完計畫來補足,但是直覺告訴我背景安裝這種會碰到系統檔案的東西肯定會搞出一堆問題,雖然我的程式只是自己練習不過我習慣以這樣要求自己,如果只是自己能用就好的話根本就不會進步。後來有第二個似乎可用的解決方案是調用MultiByteToWideChar API,測試的結果也是不能用,而且很多人好像也測試過都不能用,所以對這個方案選擇放棄。查到這我已經失去耐心,於是我就決定土法煉鋼自己作一個Codepage算了。
原則上這篇文章毫無技術成分,只是分享已經寫好的工具給同樣遇到這種問題的朋友,由於Codepage只是用來作字元跟編碼比對,所以這邊就不貼上它的程式碼,因為我怕貼了網頁會開不動...僅貼上Encoder的部分。
[完整程式碼下載:Big5EncoderFullDemo.zip]
※全文歡迎轉載但請註明出處,謝謝。※
在開始貼上程式碼之前先做一下功能展示,首先是先用.Net內建的Encoding來編碼一些難字跟日文並且轉換回文字:
沒錯,我們現在得到了一堆063(問號),這幾天弄telnet下來我已經看這種東西看到快吐了。
為了避免我真的吐出來我們趕快來試試看自製的Encoder:
感謝上帝,經過土法煉鋼的自製Encoder轉換之後,現在我的程式可以支援Big5編碼下的日文了。
以下附上Encoder部分的程式碼:
{
/// <summary>
/// 將指定位元組陣列中的所有位元組解碼成字串。
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static String GetString(Byte[] data)
{
Byte[] m_Data = data;
StringBuilder m_StrBuilder = new StringBuilder();
int m_idx = 0;
while (m_idx < m_Data.Length)
{
if
(
(
m_Data[m_idx] >= 0x81 &&
m_Data[m_idx] <= 0xFE
)
&&
(
m_idx + 1 < m_Data.Length &&(
(
m_Data[m_idx + 1] >= 0x40 &&
m_Data[m_idx + 1] <= 0x7E
)
||
(
m_Data[m_idx + 1] >= 0xA1 &&
m_Data[m_idx + 1] <= 0xFE
))
)
)
{
m_StrBuilder.Append(Big5CodepageFull.GetChar(m_Data[m_idx], m_Data[m_idx + 1]));
m_idx += 2;
}
else
{
m_StrBuilder.Append(ASCIICodepage.GetChar(m_Data[m_idx]));
m_idx++;
}
}
return m_StrBuilder.ToString();
}
/// <summary>
/// 將指定 String 中的所有字元編碼成位元組序列。
/// </summary>
/// <param name="s">String,包含要編碼的字元。</param>
/// <returns></returns>
public static Byte[] GetBytes(String s)
{
MemoryStream m_ResultStream = new MemoryStream();
foreach (Char c in s)
{
if (c >= 0 && c <= 125)
m_ResultStream.WriteByte((Byte)ASCIICodepage.GetCode(c));
else
{
Byte[] m_tempArray = BitConverter.GetBytes(Big5CodepageFull.GetCode(c));
m_ResultStream.WriteByte(m_tempArray[1]);
m_ResultStream.WriteByte(m_tempArray[0]);
}
}
Byte[] m_Result = m_ResultStream.ToArray();
m_ResultStream.Close();
m_ResultStream.Dispose();
return m_Result;
}
}