シーザー暗号で遊ぼう


暗号とかパスワード系は1年ちょっと前に
ファミコン時代のセーブ用のパスワード作ってみるで遊んだっきりだたので、
今日はシーザー暗号で遊びます^^
ワンタイムパッドとかってのもきになったけど簡単なのから遊ぶ。

シーザー暗号(wikipedia)
小さい頃に秘密のお手紙とか言って遊んだような気もする。

概念的な

やりかたはとってもシンプル。文章全体を何文字かシフトさせるだけ。
たとえば ayumegu なら + 1 で bzvnfhv となります。
シフトする関係上英語とかひらがなとかになるかな。漢字は表つくるのしんどそう・・・。

まずは変換テーブル?みたいなものを定義

この変換テーブルをめっちゃくちゃにしたらより解析難易度が上がってもっとわけわかんなくなりそうで面白そうだけど・・・
解読してくれる相手もテーブル知ってなきゃいけないもんね・・・・。
あ、でもそこまでしても長い文章になると頻度解析とかで結構わかるっぽいですね。
英語の文章の場合E,T,A,O,I,Nがよく使われるってあったな。
あ、でも日本語ならかなり大丈夫なんじゃないかな・・・。なんて。
ひらがなをローマ字にしてこれをやるのもいい感じなきがするな。
英単語だとどうしても単語と単語の間にスペース入っちゃうからね〜・・・。

まぁ今回はこんな感じにしてみました。
abcdefghijklmnopqrstuvwxyz0123456789

作成

シンプルだからあっという間に完成。


public class CaeserCipher : MonoBehaviour {

    public const string TABLE = "abcdefghijklmnopqrstuvwxyz0123456789";

    void Start()
    {
        Debug.Log(CreateCaeserCipher(1,"ayumegu"));
    }

    // 暗号文作成と解析
    public string CreateCaeserCipher(int no, string str)
    {
        string result = "";
        for(int i = 0; i < str.Length; i++)
        {
            int charNo = GetCharNo(str.Substring(i, 1));
            if(charNo != -1)
            {
                int tableNo = charNo + no;
                if(tableNo >= TABLE.Length) tableNo -= TABLE.Length;
                if(tableNo < 0) tableNo += TABLE.Length;
                result += TABLE[tableNo];
            }
            else
            {
                Debug.LogError("使用できない文字が使われています" + str);
                return null;
            }

        }

        return result;
    }

    // 文字が何番目か取得
    public int GetCharNo(string str)
    {
        for(int i = 0; i < TABLE.Length; i++)
        {
            if(TABLE[i].ToString() == str)
            {
                return i;
            }
        }
        return -1;
    }
}

実行結果はこんな感じ

もどすときはこうしてあげれば元の文字にもどります。

CreateCaeserCipher(-1,"bzvnfhv");

あ、大文字小文字の考慮わすれてたけどまぁいいや。
これはここまで。