Python 3 で ROT13 (シーザ暗号) を実装する

heroImage

1. はじめに

Python 3 には ROT13 が組み込まれているため,シーザー暗号をフルスクラッチで実装する必要はありません。しかし,鍵が 13 で固定されているため,汎用性に欠けています。そこで,本記事ではシーザー暗号の暗号化,復号化,及び,解析 (ブルートフォースアタック) を行うスクリプトを Python 3 で実装し,実行結果を確認します。また,本記事内で行っている作業は,以下の環境下で実行したものです。

2. 暗号化スクリプト

以下の平文を暗号化するスクリプトを任意のフォルダ内に encryption.py というファイル名で保存します。encryption.py を実行し,暗号化したい平文と鍵を入力すると,暗号文が出力されます。

encryption.py
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
def encrypt(str, key):
5
ciphertext = ""
6
7
for ch in list(str):
8
if 'A' <= ch <= 'Z':
9
ciphertext += chr((ord(ch) - ord('A') - key) % 26 + ord('A'))
10
elif 'a' <= ch <= 'z':
11
ciphertext += chr((ord(ch) - ord('a') - key) % 26 + ord('a'))
12
else:
13
ciphertext += ch
14
15
return ciphertext
16
17
if __name__ == '__main__':
18
plaintext = input("PLEASE INPUT PLAINTEXT : ")
19
key = input("PLEASE INPUT KEY : ")
20
ciphertext = encrypt(plaintext, int(key))
21
22
print("CIPHERTEXT : " + ciphertext)
23
24
input("PLEASE PRESS ANY")
Terminal window
1
$ python3 encryption.py
2
PLEASE INPUT PLAINTEXT : Apple
3
PLEASE INPUT KEY : 13
4
CIPHERTEXT : Nccyr
5
PLEASE PRESS ANY

3. 復号化スクリプト

以下の暗号文を復号化するスクリプトを任意のフォルダ内に decryption.py というファイル名で保存します。decryption.py を実行し,暗号文と鍵を入力すると,復号された平文が出力されます。

decryption.py
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
def deencrypt(str, key):
5
plaintext = ""
6
7
for ch in list(str):
8
if 'A' <= ch <= 'Z':
9
plaintext += chr((ord(ch) - ord('A') + key) % 26 + ord('A'))
10
elif 'a' <= ch <= 'z':
11
plaintext += chr((ord(ch) - ord('a') + key) % 26 + ord('a'))
12
else:
13
plaintext += ch
14
15
return plaintext
16
17
if __name__ == '__main__':
18
ciphertext = input("PLEASE INPUT CIPHERTEXT : ")
19
key = input("PLEASE INPUT KEY : ")
20
plaintext = deencrypt(ciphertext, int(key))
21
22
print("PLAINTEXTtext : " + plaintext)
23
24
input("PLEASE PRESS ANY")
Terminal window
1
$ python3 decryption.py
2
PLEASE INPUT CIPHERTEXT : Nccyr
3
PLEASE INPUT KEY : 13
4
PLAINTEXTtext : Apple
5
PLEASE PRESS ANY

4. 解析スクリプト

以下の暗号文をブルートフォースアタックによって解析するスクリプトを任意のフォルダ内に bfa.py というファイル名で保存します。bfa.py を実行し,暗号文を入力すると,総当りで解析された平文が出力されます。

bfa.py
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
def deencrypt(str, key):
5
plaintext = ""
6
7
for ch in list(str):
8
if 'A' <= ch <= 'Z':
9
plaintext += chr((ord(ch) - ord('A') + key) % 26 + ord('A'))
10
elif 'a' <= ch <= 'z':
11
plaintext += chr((ord(ch) - ord('a') + key) % 26 + ord('a'))
12
else:
13
plaintext += ch
14
15
return plaintext
16
17
if __name__ == '__main__':
18
ciphertext = input("PLEASE INPUT CIPHERTEXT : ")
19
20
for i in range(1, 26):
21
print('{0:2d}'.format(i) + " : " + deencrypt(ciphertext, i))
22
23
input(input("PLEASE PRESS ANY"))
Terminal window
1
$ python3 bfa.py
2
PLEASE INPUT CIPHERTEXT : Nccyr
3
1 : Oddzs
4
2 : Peeat
5
3 : Qffbu
6
4 : Rggcv
7
5 : Shhdw
8
6 : Tiiex
9
7 : Ujjfy
10
8 : Vkkgz
11
9 : Wllha
12
10 : Xmmib
13
11 : Ynnjc
14
12 : Zookd
15
13 : Apple
16
14 : Bqqmf
17
15 : Crrng
18
16 : Dssoh
19
17 : Ettpi
20
18 : Fuuqj
21
19 : Gvvrk
22
20 : Hwwsl
23
21 : Ixxtm
24
22 : Jyyun
25
23 : Kzzvo
26
24 : Laawp
27
25 : Mbbxq
28
PLEASE PRESS ANY

5. おわりに

本記事では,シーザー暗号の暗号化,復号化,及び,解析 (ブルートフォースアタック) を行うスクリプトを Python で実装し,その実行結果を確認することが出来た。世の中には,シーザー暗号の他にユニークな古典暗号が数多く存在しています。そこで,今後はそれらの暗号の実装にも取り組んでいきたいと考えています。