単一換字式暗号を実装してみる

情報セキュリティ

こんにちは。前回、突然写像をテーマに書いてみました。その理由は、暗号について書いてみようと思ったためです。十分暗号についての知識を持っているわけではないのですが、おそらく復号できる暗号は単射になっているはず!と思い、写像について書いてみました。

今回は古典的な暗号の一つである単一換字式暗号を取り上げます。

単一換字式暗号とは

まず換字式暗号は、平文を1文字ずつまたは何文字かをまとめて、別の文字や記号に置き換えていく暗号です。その中で、同じ文字に対して常に同じ変換をする暗号を単一換字式暗号というそうです。例えば、’a’の文字が出現したら必ず’p’に、’b’の文字が出現したら必ず’g’の文字に…と対応した文字に変換していくことになります。

復号するためには、逆の方向に変換すればよいことになります。

換字するための規則を作る

換字するための規則を作ります。手作業でランダムに並べ替えてもよいのですが、プログラムで作ってみましょう。言語は何となくPythonです。使用できる文字は、アルファベットの小文字26文字だけに限定します。

import random

plain = 'abcdefghijklmnopqrstuvwxyz'
key = ''.join( random.sample( plain, len(plain) ) )
print( plain )
print( key )

このプログラムの解説はしませんが、ランダムに並べ替えた文字列のリストを作ってつなぎ合わせたものがkeyになっています。その結果、次のような結果を得ました。

abcdefghijklmnopqrstuvwxyz
pguxylqiaznfrbokwhdemtcsjv

確かめるまでもありませんが、この写像は全単射になっています。

逆写像により復号できます。

上の行の文字を下の行の文字に変換することにより、暗号を作ることにしましょう。

暗号化するプログラム

次に暗号化します。難しいことを考えないで、単純に1文字ずつ変換していくことにします。関数encryptの引数は、暗号化する文、変換前の文字(列)、変換後の文字(列)の3つです。2つ目と3つ目の引数を入れ替えると復号することができます。

def encrypt( text, original, encode ):
  result = ''
  for letter in text:
    index = original.index( letter )
    result += encode[index]
  return result


if __name__ == '__main__':
  plain_alphabet  = 'abcdefghijklmnopqrstuvwxyz'
  cipher_alphabet = 'pguxylqiaznfrbokwhdemtcsjv'

  plain_text  = 'practicemakesperfect'
  cipher_text = encrypt( plain_text, plain_alphabet, cipher_alphabet )
  decode_text = encrypt( cipher_text, cipher_alphabet, plain_alphabet )
  print( plain_text )
  print( cipher_text )
  print( decode_text )
  print()


  plain_text  = 'thepenismightierthanthesword'
  cipher_text = encrypt( plain_text, plain_alphabet, cipher_alphabet )
  decode_text = encrypt( cipher_text, cipher_alphabet, plain_alphabet )
  print( plain_text )
  print( cipher_text )
  print( decode_text )

実行結果です。2つの文に対して、元の文・暗号化した文・復号した文を表示しています。

practicemakesperfect
khpueauyrpnydkyhlyue
practicemakesperfect

thepenismightierthanthesword
eiykybadraqieayheipbeiydcohx
thepenismightierthanthesword

単一換字式暗号の弱点

単一換字式暗号の弱点は、出現頻度を分析することで解析できることです。例えば多くの文章ではqとかxとかzなんて文字はほとんど出現しません。逆に母音の文字とかtとかsとかは多く出現します。また、文章になったときは、冠詞であるとか前置詞のような出現頻度が高い単語に着目すると解読できるようです。

最後に。

Practice makes perfect.

The pen is mightier than the sword.

それではまた。

Posted by 春日井 優