Base64とはアルファベット「 a~z , A~Z 」と数字「 0~9 」、一部の記号「 + と / 」)と末尾の記号「 = 」を用いてデータを変換する方式のことです。
これを用いることで普段テキストディタなどで文字化けしてしまうようなバイナリデータを文字列として表示できるようになります。
例えばメール送信時の添付ファイルなどはこの方式を利用して送受信を行っています。
そのほかにも、文字列でバイナリデータを扱いたい場合などに有効です。
注意点としては、エンコードされた文字は簡単にデコードできるため、暗号としては利用できません。
またエンコードには一定の規則性があるため、出力された文字列を見ればBase64でエンコードされていることがわかります。
バイナリデータをBase64文字列にエンコード
今回は、サンプルプログラムとして画像をBase64に変換してみようと思います。
Base64で変換するためには、バイナリデータをbyteの配列にしてToBase64String関数に渡す必要があります。
string base64string = "";
//画像ファイルの読込
System.Drawing.Image bitmap = System.Drawing.Bitmap.FromFile(@"D:\Pictures\sample.bmp");
//バイト配列の変換
System.Drawing.ImageConverter ic = new System.Drawing.ImageConverter();
byte[] b = (byte[])ic.ConvertTo(bitmap, typeof(byte[]));
//Base64へのエンコード
base64string = System.Convert.ToBase64String(b);
Base64文字列をバイナリデータにデコード
バイナリデータに戻す場合は、エンコードの逆を行えば元に戻すことができます。
//Base64からデコード
byte[] decode = System.Convert.FromBase64String(base64string);
//Imageに戻す
System.Drawing.ImageConverter imgconv = new System.Drawing.ImageConverter();
System.Drawing.Image img = (Image)imgconv.ConvertFrom(decode);
サンプル
実際に動作確認してみます。
string base64string = "";
//画像ファイルの読込
Image bitmap = System.Drawing.Bitmap.FromFile(@"D:\Pictures\sample.bmp");
//画面に表示
this.picSrc.Image = bitmap;
//バイト配列の変換
System.Drawing.ImageConverter ic = new ImageConverter();
byte[] b = (byte[])ic.ConvertTo(bitmap, typeof(byte[]));
//Base64へのエンコード
base64string = System.Convert.ToBase64String(b);
//出力
this.txtBase64.Text = base64string;
//----------------------------------------------------------------------------------
//Base64からデコード
byte[] decode = System.Convert.FromBase64String(base64string);
//Imageに戻す
ImageConverter imgconv = new ImageConverter();
Image img = (Image)imgconv.ConvertFrom(decode);
//画面に表示
this.picdest.Image = img;
実行結果
byte配列にするための関数
C#でBase64に変換するToBase64String関数はByte配列にする必要があります。
またFromBase64Stringはbyte配列を戻り値として返すのでByte配列を対象の型に変換する必要があります。
文字列からbyte配列への相互変換
文字列をbyte配列にする
string s = "テスト用文字列";
//UTF8でバイト化
byte[] b = System.Text.Encoding.UTF8.GetBytes(s);
byte配列から文字列にする
//BASE64からデコードされたバイト配列を文字列に戻す
string s2 = System.Text.Encoding.UTF8.GetString(decode);
数値からbyte配列への相互変換
数値のbyte配列にする場合は、BitConverterを使います。
数値をbyte配列にする
//整数
int i = 150;
byte[] byteInts = BitConverter.GetBytes(i);
//浮動小数
double d = 23.554;
byte[] byteDoubles = BitConverter.GetBytes(d);
byte配列を数値にする
//整数
int i2 = BitConverter.ToInt32(byteInts, 0);
//浮動小数
double d2 = BitConverter.ToDouble(byteDoubles, 0);
画像
画像をbyte配列にする
//対象の画像
Image bitmap = System.Drawing.Bitmap.FromFile(@"D:\Pictures\sample-s.jpg");
//byte配列に変換
System.Drawing.ImageConverter ic = new ImageConverter();
byte[] b = (byte[])ic.ConvertTo(bitmap, typeof(byte[]));
byte配列を画像にする
//Imageに戻す
ImageConverter imgconv = new ImageConverter();
Image img = (Image)imgconv.ConvertFrom(decode_bytes);
その他のオブジェクト
その他オブジェクトをByte配列に変換する場合は、以下のように関数を作成しました。
オブジェクトなのでどんな型も変換可能です。
オブジェクトをbyte配列にする関数
//バイト配列にする関数を作成
byte[] ObjectToByteArray(object obj) {
//オブジェクトがnullの場合は、処理しないでnullを返す
if(obj == null) return null;
//
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream()) {
bf.Serialize(ms, obj); return ms.ToArray();
}
}
byte配列をオブジェクトに戻す関数
上記のObjectToByteArray関数で変換したものを元に戻します。他の方法で作成したbyte配列をやってもうまくもとに戻る保証はありません。
public T ByteArrayToObject<T>(byte[] bytes)
{
//オブジェクトがnullの場合は、処理しないで返す。
if (bytes == null) return default(T);
//byte配列にする
BinaryFormatter bf = new BinaryFormatter();
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes))
{
return (T)bf.Deserialize(ms);
}
}
サンプル
先ほどの画像をBase64でエンコードしたものを変えてみます。
string base64string = "";
//画像ファイルの読込
Image bitmap = System.Drawing.Bitmap.FromFile(@"D:\Pictures\sample-s.jpg");
//画面に表示
this.picSrc.Image = bitmap;
//バイト配列の変換
byte[] b = ObjectToByteArray(bitmap);
//Base64へのエンコード
base64string = System.Convert.ToBase64String(b);
//出力
this.txtBase64.Text = base64string;
//----------------------------------------------------------------------------------
//Base64からデコード
byte[] decode = System.Convert.FromBase64String(base64string);
//Imageに戻す
Image img = ByteArrayToObject<Image>(decode);
//画面に表示
this.picdest.Image = img;
まとめ
バイナリエディタはそのままだと文字列として送受信できないので、Base64をつかって文字列として扱えるようにすれば問題なく利用できます。
この記事が皆様のお役に立てたら幸いです。