暗号化テキストエディタ作る(2)
仕事があまりにも忙しく、すっかり更新する機会を逸していました。
今回は、前回の内容をあまり読んでいただかなくても大丈夫なように書きたいと思います。
まずは、テキストボックス上に書かれたテキストデータを、暗号化してファイルにセーブするための処理を考えたいと思います。
流れとしては、以下のようにしてみました。
- テキストボックスの内容を、1文字単位で拾ってくる。
- 一文字は2バイトである 。.NETFrameworkでは、文字列はUnicodeで内部的に保存されているため、一文字は全角文字も半角文字も、2バイトになる
- その一文字の上位1バイトと、下位1バイトを別々の変数にそれぞれ入れる。
- それぞれの変数の内容を暗号化する(ここでは簡単に、ローテーションを使います)
- 暗号化の終わった2つの変数を、再び合成する。ただし、本来上位に入るべき変数の内容を下位に、下位に入るべき変数の内容を上位に入れるようにして、暗号度を高める
- この合成した内容を、ファイルに書き込む
- 上記の処理を、テキストボックスの文字の全てに対して行う
さて、上記の流れのうち、4の暗号化の部分がポイントになってきますが、ここでは変数の内容(8ビット)を1ビット、右か左にローテーション(シフトして、はみ出したビットを空き部分に入れる)することで、そのままでは文字として表示できないようにする方法を取ります。
この部分は別途関数を作ることで、全体を分かりやすいものにしたいと思います。
public static void my_rotate(ref byte target, string direction)
{
if (direction.ToLower() == "right")
{
int onebit = (int)target & 0x0001;
target = (byte)((int)target >> 1);
if (onebit != 0)
target = (byte)((int)target | 0x0080);
else
target = (byte)((int)target & 0x007f);
}
else //left
{
int onebit = (int)target & 0x0080;
target = (byte)(target << 1);
if (onebit != 0)
target = (byte)((int)target | 0x0001);
else
target = (byte)((int)target & 0x00fe);
}
}
この関数は、第一引数に、ローテーションしたい変数(Byte型)を渡し、第二引数には"left"か"right"を渡すことで右ローテートなのか左ローテートなのかを指定します。
それでは全体の処理です。
FileStream filename = new FileStream(common.file_location, FileMode.Create);
BinaryWriter bw = new BinaryWriter(filename);
string buf = textBox1.Text;
for (int i = 0; i < buf.Length; i++)
{
ushort a = buf[i];
byte high_8 = (byte)((a & 0xFF00) >> 8);
byte low_8 = (byte)(a & 0x00FF);
my_rotate(ref high_8, "right");
my_rotate(ref low_8, "left");
ushort out_16 = low_8;
out_16 = (ushort)((out_16 << 8) | high_8);
bw.Write(out_16);
}
bw.Close();