UTF-8の文字列とバイト配列の相互変換をしたい

2022年現在、Windowsで扱う文字列はユニコードですが、ネットワークに飛び交う文字列のバイト配列は UTF-8 で扱うことがほとんどです。

  • 文字列をUTF-8として byte 配列に変換する。
  • UTF-8なデータが格納された byte 配列を文字列に変換する。

そういう相互変換することができないと、まともなネットワーク系アプリケーションを作成することはできません。TcpListener クラスや TcpClient クラスでアプリケーションを作るときに必ずこの問題に直面するはずです。

  • 文字列を byte 配列に変換するのは System.Text.Encoding.UTF8.GetBytes(); メソッドを使います。
  • byte 配列を文字列に変換するのは System.Text.Encoding.UTF8.GetString(); メソッドを使います。

using System;
using System.Text;
using System.Windows.Forms;

namespace aaa
{

	public partial class Form1 : Form
	{

		public Form1()
		{
			InitializeComponent();
		}

		private void button1_Click( object sender, EventArgs e )
		{

			String str0 = "あいう0123かきく";

			// バイト配列に変換する前の文字列を表示する.
			MessageBox.Show( str0, "変換まえ" );

			// 文字列をUTF8の扱いでバイト配列に変換する.
			byte [] data = Encoding.UTF8.GetBytes( str0 );

			// バイト配列にどんな値が入っているか調べる.
			StringBuilder sb = new StringBuilder();
			for ( int k = 0; k < data.Length; k++ )
			{
				String s = String.Format( "[{0}]\t0x{1:x2}", k, data[k] );
				sb.AppendLine( s );
			}

			// バイト配列の要素のナマの値をメッセージボックスで表示する.
			MessageBox.Show( sb.ToString().Trim(), "配列の要素の値" );

			// バイト配列をUTF8として解釈し文字列を得る.
			String str1 = Encoding.UTF8.GetString( data );
			
			// -----------------------------------------------------------
			// ためしに Shift-JIS にしてみると盛大に文字化けする.
			// String str1 = Encoding.GetEncoding(932).GetString( data );
			// -----------------------------------------------------------

			// バイトから変換された文字列を表示する.
			MessageBox.Show( str1, "変換後" );

		}

	}

}

上記のコードの実行結果を以降に示します。

まず、22行目の実行結果を Fig. 1 に示します。

Fig. 1 変換前の文字列

その文字列を UTF-8 として byte [] 配列に変換します。25行目です。Encoding.UTF8.GetBytes() です。

36行目の実行結果を Fig. 2 に示します。UTF-8 の文字コード別にわかりやすくした内容を Fig. 3 に示します。

Fig. 2 バイト配列に格納された値
Fig. 3 バイト配列に格納された値を文字ごとに示す

次に、39行目で、バイト配列から文字列に変換します。Encoding.UTF8.GetString() メソッドです。

その結果を Fig. 4 に示します。47行目です。

Fig. 4 バイト配列から適切な文字コード解釈で変換した場合

41~44行目をコメントインして、UTF-8 でデータ格納された byte [] 配列のデータを、むりやり Shift-JIS として解釈し文字列に変換した結果を Fig. 5 に示します。

Fig. 5 バイト配列から不適切な文字コード解釈で変換した場合

プログラミングの途中でこういう文字列が出くわすと、ほんとうにウンザリしますが、大方の場合は UTF-8 を意識すれば目的の動作になると思います。( しつこいですが2022年現在のトレンドであって、将来もそうすればうまくいくということではありません )