シーザー暗号を Ruby で解読する
はじめに
暗号について勉強し始めた経緯
「暗号技術入門 秘密の国のアリス」というテキストを読み始めました。
- 作者: 結城浩
- 出版社/メーカー: SBクリエイティブ株式会社
- 発売日: 2013/12/04
- メディア: Kindle版
- この商品を含むブログ (3件) を見る
なぜこのテキストを読み始めたかというと、
読書週間が廃れつつあるので、頑張って復活させたい。結城浩さんの本も読みたい読みたい詐欺のままだしな。
— QUANON (@quanon86) March 25, 2015
とつぶやいたら、結城浩さんご本人から
@quanon86 よろしくですー(^^)
— 結城浩 (@hyuki) March 25, 2015
というリプライを頂いたので、急遽 Amazon の Kindle ストアで結城さんの著書を漁り、最近セキュリティに関心があるのでこのテキストを購入してみたというわけです。本当は 数学ガール シリーズをまず読もうと思っていたんですけどね。
おかげさまで「『読みたい読みたい詐欺』脱却詐欺」から脱することができました。
以下、テキスト内にあったクイズ (序盤の章の簡単なものですが) を解いてみようと思います。
シーザー暗号の解読
シーザー暗号とは
シーザー暗号 (Caesar cipher) とは、ジュリアス・シーザー (ガイウス・ユリウス・カサエル) が使っていたといわれている暗号です。ちなみにシーザーとは紀元前 100 年に生まれたローマの政治家・軍人です。
暗号といってもシーザー暗号での暗号化の仕組みは非常に単純です。平文で使われているアルファベットをそれぞれ一定数 (基本的には 3 文字) ずらすだけです。そして、暗号文のアルファベットをそれぞれ逆方向に同じ文字数だけずらせば復号できます。
Ruby で解読する
テキスト内に「シーザー暗号で暗号化された PELCGBTENCUL
という暗号文を解読せよ」というクイズがありました。これを Ruby を使って ブルート・フォース・アタック で解いてみます。
ブルート・フォース・アタックとは、考えうるすべての組み合わせ試す暗号解読方法です。つまりはゴリ押しです。シーザー暗号の場合、アルファベットは 26 種類なので、ずらしうる文字数も 0 〜 25 個の 26 通りです。人間が手動で試すことのできるレベルの数なので、コンピュータで解けば一瞬ですね。
def decrypt_with_caesar(ciphertext, key_number) alphabets = Array('A'..'Z') ciphertext.each_char.inject('') do |decrypted_string, char| index = (alphabets.index(char) - key_number) % alphabets.length decrypted_string << alphabets[index] end end def brute_force_attack(ciphertext) (0..26).map { |n| decrypt_with_caesar(ciphertext, n) } end
この brute_force_attack
というメソッドを実行してみます。(Awesome Print という Gem の ap
メソッドを利用して結果を整形して出力しています。)
ap brute_force_attack('PELCGBTENCUL')
[ [ 0] "PELCGBTENCUL", [ 1] "ODKBFASDMBTK", [ 2] "NCJAEZRCLASJ", [ 3] "MBIZDYQBKZRI", [ 4] "LAHYCXPAJYQH", [ 5] "KZGXBWOZIXPG", [ 6] "JYFWAVNYHWOF", [ 7] "IXEVZUMXGVNE", [ 8] "HWDUYTLWFUMD", [ 9] "GVCTXSKVETLC", [10] "FUBSWRJUDSKB", [11] "ETARVQITCRJA", [12] "DSZQUPHSBQIZ", [13] "CRYPTOGRAPHY", [14] "BQXOSNFQZOGX", [15] "APWNRMEPYNFW", [16] "ZOVMQLDOXMEV", [17] "YNULPKCNWLDU", [18] "XMTKOJBMVKCT", [19] "WLSJNIALUJBS", [20] "VKRIMHZKTIAR", [21] "UJQHLGYJSHZQ", [22] "TIPGKFXIRGYP", [23] "SHOFJEWHQFXO", [24] "RGNEIDVGPEWN", [25] "QFMDHCUFODVM", [26] "PELCGBTENCUL" ]
ちなみに配列のインデックスが暗号化時にずらした文字数に相当します。
この結果を見ると 13 番目が CRYPTOGRAPHY
という意味のある単語 (英語で「暗号」という意味) なので、これが解答ですね。