シフト暗号の総当たり
まえがき
どうもです。お久しぶりです。
インターンや就職に提出するための技術的な話をする場が欲しいと思い、今日から定期的になんかしら書いていこうと思います。(ついでにMarkdownも慣れたい)
初回はシーザー及びシフト暗号です。(配属された研究室が暗号系だったので)
シーザー暗号
アルファベットで表記されたある文字列(以降平文)を3文字ずらすことで暗号化する。
例)
平文:abcdefg
暗号:DEFGHI
有名な奴です。ゲームやアニメなんかでも使われることがありますね。
実装も簡単ですが、有名なだけに突破もされやすいです。
シフト暗号
シーザー暗号の改良版。ずらす値を固定するのではなく、任意の数とする方法。
例)
平文:abcdefg
暗号:BCDEFGH
実装
総当たりでの復号の実装です。
#include <iostream> #include <bits/stdc++.h> #include <string> using namespace std; int main(void){ string s; cout << "入力文字列:"; cin >> s; cout << "復号文字列:" << endl; for(int i=0;i<26;i++){ for(int j=0;j<s.size();j++){ cout << char('a'+(s.at(j)-'A'+i)%26); } cout << endl; } }
実行結果
解説
任意の文字列sについて、i文字ずつずらして表示するプログラムです。
アルファベットが26文字なのでそれを26回for文で回して総当たりします。
多分一番わかりづらいであろう以下の1行についてだけ解説します。
cout << char('a'+(s.at(j) - 'A' + i)%26);
s.at(j) - 'A' + i
暗号化された文字列のj文字目[s.at(j)]が「A」から何文字ずれているかを計算し、ずらす分の数字iを加算します。
'a'+(s.at(j) - 'A' + i)%26
加算した対象文字を26で割り、その余り分を'a'に加算することで、i文字分ずらして表示しています。
文字コードがわからん、って人はAtCoder あたりを見てください。
今回の場合、意味を成した文字列になっているのは「helloworld」、よって暗号化に使われた鍵は、ずれた文字数である「4」ですね。
あとがき
今回書くにあたって参考にした本:暗号技術のすべて
平文を小文字、暗号を大文字で書くとかって決まりがあるの、初めて知りました。そういやLinuxでauthorized_keysみたとき全部大文字だったなーなんてことを思い返しながら読んでました。
あとMarkdown、ちゃんと書くのは初めてだったんですが、正直よくわからんまま書き終えました。
まあこれから慣れていくでしょう。週に1本出せたらいいかなって感じのペースで更新していこうと思います。