ブログのネタが無さすぎて苦しんでいたが、ふと見るとペットボトルが目に留まった。今年の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を入力してください」という意味である。