日本語でシーザー暗号を解読してみよう
日本語プログラミング言語「なでしこ」公式サイト |
最近では機密情報の流出を防ぐため、大切なデータを保存する際には、暗号化して保存するようにと言われています。しかし、その際、どのような暗号化を行うかは重要な問題と言えます。今回は、暗号への理解を深めるために、世界で最も簡単な暗号である「シーザー暗号」を例にして、自作プログラムを作ってみましょう。
シーザー暗号とは?
最初に、「シーザー暗号(シフト暗号)」について紹介します。そもそも「シーザー暗号」の「シーザー(英語: Caesar)」というのは、古代ローマの指導者ガイウス・ユリウス・カエサルのことで、カエサルが暗号として利用した事から、この名称がつけられています。
シーザー暗号は、とても簡単な仕組みです。暗号化を行うには、ABCD...のようなアルファベットの並びを3文字分後ろにずらします。つまり「A」を「D」に、「B」を「E」に、「C」を「F」に置き換れることで暗号化を行います。例えば、「CAT」であれば「FDW」、「I LOVE YOU」であれば「L ORYH BRX」となります。
とても簡単な仕組みなのですが、シーザー暗号で暗号化することにより、普通の文章としては読めなくなることが分かるでしょう。
それでは、逆に、暗号化した暗号文を読むには、どうしたら良いのかと言うと、3文字前にずらします。つまり、「D」を「A」に、「E」を「B」に変えます。このようにすると、シーザー暗号を元の文章に戻すことができます。
なでしこでシーザー暗号のプログラムを作ってみよう
それでは、まずは、忠実にシーザー暗号で文章を暗号化するプログラムを作ってみましょう。なでしこ簡易エディタにアクセスしたら、以下のプログラムを入力して実行してみましょう。
# 文章の文字をVだけずらす --- (*1)
●(SをVで)シフト処理とは
R=「」
L=Sの文字数
Iを1からLまで繰り返す
SでIから1を文字抜出して、大文字変換して、CHに代入。
C=ASC(CH)
もし、(C >= 65)かつ(C <= 90)ならば
R = R & CHR((C - 65 + V + 26) % 26 + 65)
違えば
R = R & CH
ここまで。
ここまで
Rを戻す。
ここまで。
# 暗号化--- (*2)
●(Sを)シーザー暗号化とは
Sを3でシフト処理。
ここまで
# 復号化--- (*3)
●(Sを)シーザー復号化とは
Sを-3でシフト処理。
ここまで
# 暗号化のテスト --- (*4)
N1=「I LOVE YOU!」
N2=N1をシーザー暗号化
N3=N2をシーザー復号化
「元文章: {N1}
暗号化: {N2}
復号化: {N3}」を表示。
プログラムを実行すると、「I LOVE YOU!」を暗号化し、次いで、暗号化したデータを元に戻します。ちなみに、暗号化したデータを元に戻すことを「復号化」と言います。
ここでは、プログラムの(*4)の部分で「I LOVE YOU!」という文章を変換していますが、ここを「THIS IS A PEN.」など、他の文章に書き換えて動作を確認してみましょう。
プログラムを確認してみましょう。プログラムの(*1)の部分では、文字列Sの各文字について、それがアルファベットであれば、V文字分だけ後ろにずらす処理を行う関数を定義しています。
そして、(*2)の部分では、暗号化処理を行います。シーザー暗号では、3文字分だけ後ろに文字をずらすため、(*1)で定義した関数「シフト処理」を3で呼びだします。
最後の(*4)の部分で、暗号化と復号化のテストを行います。
逆に、(*3)の部分では、暗号化されたデータの復号化を行います。シーザー暗号では3文字だけ後ろにずらすので、復号化するには、3文字分前にずらせば良いことになります。
それから、(*1)の部分で、文字をずらす処理ですが、各文字について、以下の処理を行っています。
そもそも、文字コードというのは、何でしょうか。コンピューターでは、文字を表示するために、文字の一つずつに文字コードの番号を振っているのです。例えば、文字「A」には65、「B」には66、「C」には67という具合です。この時、文字を文字コードに直すのが、関数『ASC(文字)』で、文字コードから文字に直すのが『CHR(文字コード)』です。図にすると、以下のようになるでしょう。
箇条書きにすると以下の手順になるでしょう。
・(1) 文字を文字コードに直す
・(2) 文字コードに対して3を足す
・(3) 上記(2)の結果を再度文字に変換する
日本語も暗号化できるように改良しよう
先ほど作ったプログラムは、シーザー暗号を忠実に再現するために、アルファベットのみを暗号化するようにしていました。しかし、それだと不便なので、日本語も暗号化できる改良してみましょう。改良と言っても、アルファベットだけを暗号化するという処理を外すだけです。その分、プログラムも短くなります。
また、シーザー暗号では、3文字ずらすと決まっていましたが、3文字固定だと、すぐに解読できてしまうので、何文字ずらすかも、毎回指定するようにしてみましょう。
●(SをNOで)シフト処理とは
R=「」
Iを1から(Sの文字数)まで繰り返す
SでIから1を文字抜出して、CHに代入。
R = R & CHR(ASC(CH) + NO)
ここまで。
Rを戻す。
ここまで。
N1=「泣くのに時があり、笑うのに時がある。」
N2=N1を10でシフト処理。
N3=N2を-10でシフト処理。
「元文章: {N1}
暗号化: {N2}
復号化: {N3}」を表示。
プログラムを実行すると、以下のようになります。暗号文を見ると、意味不明で文字化けしているように見えることでしょう。
シーザー暗号はすぐに解読できてしまう
さて、ここまでシーザー暗号のプログラムを見てきましたが、文字を任意の文字数ずらすだけなので、仕組みがとても単純であることが分かるでしょう。そのため、解読も簡単です。何回か暗号文をシフト処理するだけで、暗号が解読できてしまうからです。実際、19世紀にロシア陸軍がシーザー暗号を使って通信していたところ、ドイツやオーストリアではその暗号文を難なく解読していたという記録もあります。
ですから、今回のシーザー暗号を重要な用途に利用することはできません。見た目には、厳重に暗号化されているように見えても、安易な暗号化では簡単に解読されてしまうことも分かるでしょう。実際に暗号化のプログラムを作ることで、暗号化の基本的な仕組みを理解することができたのではないでしょうか。
自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2005年IPAスーパークリエイター認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。