C#のchar型は2バイト
C#で下記のようなコードを実行してみます。
using System; class Program { static void Main(string[] args) { char c = 'あ'; int i = (int)c; Console.WriteLine(c); Console.WriteLine("size = " + sizeof(char).ToString()); Console.WriteLine("code = " + i.ToString("X")); } }
【実行結果】
あ size = 2 code = 3042
C言語のchar型は1バイトですが、C#のchar型は2バイトであることがわかります。また 'あ' に対応するコードが 3042 であることから UTF-16 であることがわかります。つまり、C#のchar型はC言語でいえばwchar_t型に相当します。
ちなみに、ソースファイルはUTF-8で保存されますが、シフトJISで保存しなおしてビルドしても実行結果は変化しません。あくまで .NETの内部形式としては文字は UTF-16 で扱われます。
バイト列にエンコード
C#のような今どきの言語の場合、文字列データの内部形式がなんであれ、いろいろな文字コードのバイト列にエンコードする手段が提供されています。例えば UTF-8 でエンコードするには下記のようにします。
using System; using System.Text; class Program { static void Main() { string s = "あいうえお"; // UTF-8でエンコード byte[] buff = Encoding.UTF8.GetBytes(s); string hexString = BitConverter.ToString(buff).Replace("-", " "); Console.WriteLine(hexString); } }
【実行結果】
E3 81 82 E3 81 84 E3 81 86 E3 81 88 E3 81 8A
'あ' に対応するコードが E38182 であることから、UTF-8だとわかります。
エンコードの行を下記のように変更するとシフトJISにエンコードできます。
// シフトJISでエンコード byte[] buff = Encoding.GetEncoding("Shift_JIS").GetBytes(s);
【実行結果】
82 A0 82 A2 82 A4 82 A6 82 A8
'あ' に対応するコードが 82A0 であることから、シフトJISだとわかります。
同様に下記のように変更すると UTF-16 にエンコードできます。
// UTF-16でエンコード byte[] buff = Encoding.Unicode.GetBytes(s);
【実行結果】
42 30 44 30 46 30 48 30 4A 30
リトルエンディアンであることに注意してください。'あ' に対応するコードが 3042 であることから、UTF-16 だとわかります。
バイト列からデコード
逆にUTF-8のバイト列を文字列にデコードするには下記のようにします。
using System; using System.Text; class Program { static void Main() { byte[] buff = { 0xE3, 0x81, 0x82, 0xE3, 0x81, 0x84, 0xE3, 0x81, 0x86, 0xE3, 0x81, 0x88, 0xE3, 0x81, 0x8A }; // UTF-8でデコード string s = Encoding.UTF8.GetString(buff); Console.WriteLine(s); } }
【実行結果】
あいうえお
シフトJISやUTF-16のバイト列の場合は下記のようにします。
// シフトJISでデコード string s = Encoding.GetEncoding("Shift_JIS").GetString(buff);
// UTF-16でデコード string s = Encoding.GetEncoding("Shift_JIS").GetString(buff);