pythonのcodecsモジュールでrot13暗号の変換をした

ブログのネタが無さすぎて苦しんでいたが、ふと見るとペットボトルが目に留まった。今年のpyconjpでもらった水のペットボトルだ。

そして、外側のフィルムには妙な問題が書いてある。

super_difficult_encryption = '?????'

import codecs
print(
	codecs.decode(
		'FRAFL ybirf Clguba naq NV!',
		super_difficult_encryption
	)
)

そのままじゃ読めない暗号を解読してくれってことだろう。
俺がいた大学の数理情報工学では暗号理論も多少勉強するし、東大の五月祭の出展では暗号を題材にしたこともある。暗号の話は多少心得がある。
復号のための鍵もないから、これで戻すとなるとrot13あたりじゃねーか?

と思ってpythonのcodecモジュールを確認すると、rot13があったので、'?????'を'rot13'に変えて実行。

SENSY loves Python and AI!

よし。無事に暗号が解読できた。なおSENSYというのはPyCon JPのスポンサーで、この水を提供してくれた企業である。

rot13とは

アルファベットを13文字ずらす暗号である。(アルファベットは全部で26文字なので、もう一度この操作をすると元に戻る。)
暗号文'FRAFL ybirf Clguba naq NV!'の最初のFを復号すると、Fの13文字先にあるSになる。

codecsモジュールとは

codecsモジュールは暗号を作るためのモジュールなのかと思ったが、そうではなさそうだ。

7.2. codecs ? codec レジストリと基底クラス
このモジュールは、標準的な Python codec (エンコーダとデコーダ) 用の基底クラスを定義し、codec とエラー処理検索プロセスを管理する内部の Python codec レジストリへのアクセスを提供します。多くの codec はテキストをバイト形式にエンコードする テキストエンコーディング ですが、テキストをテキストに、またはバイトをバイトにエンコードする codec も提供されています。
7.2. codecs — codec レジストリと基底クラス — Python 3.6.5 ドキュメント

うーん。分かりにくい。初めての人がこれを読んでも分からないよ……

このページの方に各国のエンコーディングが載っていたので、文字エンコードの方式変換をするんだろう、きっと。

ただ、codecモジュールでできることは文字エンコードの変換に限らない。
例えばBase64エンコード/デコードも可能だ。
ただし入力はbytes-like objectに限られるので、文字列をそのまま入れることはできない。

import codecs

print(
	codecs.encode(
		b'Machine Learning', 'base64_codec'
	)
)

出力:
b'TWFjaGluZSBMZWFybmluZw==\n'


入力文字列の前のbを省くと
TypeError: encoding with 'base64_codec' codec failed (TypeError: expected bytes-like object, not str)
というエラーが出た。
base64_codecを使うときは、文字列(str)じゃなくて、bytes-like objectを入力してください」という意味である。