2017年9月17日日曜日

C#でエンコーディング変換

 基本的にC#はエンコーディングの事を考えなくても良いのだけど、今回諸事情でUInt16で表現された文字を別のエンコードにする必要があったので、試してみた。

 今回はShift JISとUnicodeの変換を行った。

static UInt16 ShiftJis2Unicode(UInt16 ShiftJisChar)
{
 byte[] buff2 = Encoding.Unicode.GetBytes(
  new[] {
   Encoding.GetEncoding("Shift_JIS").GetChars(
    new [] {
     (byte)(ShiftJisChar / 256),
     (byte)(ShiftJisChar % 256),
    }
   )[0]
  });

 return ((UInt16)(buff2[0] | buff2[1] << 8));
}

static UInt16 Unicode2ShiftJis(UInt16 UnicodeChar)
{
 byte[] buff2 = Encoding.GetEncoding("Shift_JIS").GetBytes(
  new[] {
   Encoding.Unicode.GetChars(
    new[] {
     (byte)(UnicodeChar % 256),
     (byte)(UnicodeChar / 256),
    }
   )[0]
  });

 return ((UInt16)(buff2[0] << 8 | buff2[1]));
}

 Shift JISはASCIIと互換性があり、また半角カナも1バイトで表現できる。が、今回はマルチバイト文字しか考えていないので、シングルバイト文字を入れると問題が起きるはず。
 Unicodeは文字にかかわらず2バイトで表現するので、たぶん動くはず。

 UnicodeとUTF-8とかの変換は、また別の問題なので今回は扱わない。

 ちなみにC#のcharはUnicodeらしく、intに入れるとUnicodeのインデックスになる。intをcharにキャストするとUnicodeで文字化される。今回はEncoding.Unicode.GetCharsとか使ったけど、Unicode対ならcharのキャストでも良いかも。

 他のエンコーディングとの変換も同じようにすれば動くはずだけど、それぞれバイトオーダーや固定長・可変長みたいなバリエーションがあるので、ちょっと面倒。

 今回は文字単位での変換だったけど、文字列の変換だともっと簡単にできるみたいね(未確認)。

0 件のコメント:

コメントを投稿