派遣で働くエンジニアのスキルアップを応援するサイト

PRODUCED BY RECRUIT

エンジニアへの挑戦状 #02 Pythonでお宝探し【解説】

f:id:itstaffing:20220318155953j:plain

この記事は、2022年3月11日に配信した「エンジニアへの挑戦状 #02 Pythonでお宝探し」の解説となります。まだ問題を解いていない方は、こちらからご覧ください。
https://www.r-staffing.co.jp/engineer/entry/20220311_1

あなたのPythonスキルを測る問題でした。
迷わずに選択肢から解答を選べましたか?早速、解説していきます。

問題を解くための考え方

換字式暗号は古典的な暗号方法の一つで、最も有名なシーザー暗号も換字式暗号の一つです。シーザー暗号は紀元前100年ごろに発明されたと言われており、ABCという文字列をBCDのように決められた数だけズラして暗号化する方法です。

今回の問題では、これの発展系で変換先の対応表が必要になります。

単純な暗号方式なので暗号を解読するのに必要な対応表が与えられない場合でも、解読されてしまう恐れがあるので現代では実用的ではありません。重要な情報は現実的な時間で解読ができない複雑なアルゴリズムで暗号化する必要があります。

暗号化されていない文章のことを「平文(ひらぶん)」と言います。平文を解読不能な情報に変換することを暗号化と呼び、平文に戻すことを復号化と呼びます。

問題文のプログラムの中に、以下のような対応表があります。

```
    plain_chars = "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんがぎぐげご "
    encrypted_chars = "くけこそるれのぎぐよおみせかはらいえまねちもがをうふへほたろすあむげりめひさしんきやゆごわつてとなにぬ "
```

これは、「あ」を「く」に書き換え、「い」を「け」に書き換えるというように1文字ごとに変換先の文字が指定されています。最後のスペースはスペースのままです。

そして、

```
    encrypted_text = "られしふ おけぬう みすも れぎみら"
```

を復号化するのが目標です。プログラムを読むことができなくても、対応表が与えられているので1文字ずつ照らし合わせれば解読できます。

復号化は `decrypt` というメソッドで実装しています。 `decrypt`は `transform_text` メソッドを利用しており、引数は暗号文及び辞書型の変換表を持ちます。暗号文を平文に変換する変換表は `encrypted2plain_key` で、キーに暗号化されたときの文字、バリューに平文のときの文字が保存されています。 `transform_text` では、暗号文に対して変換表を使いながら1文字ずつ処理していけばいいことになります。

解説

これらを踏まえて、今回の選択肢を順に見ていきましょう。
まずは【選択肢1】です。

```
for value in key.values():
    replaced_char = key.get(value, "")
    text = text.replace(value, replaced_char)
return text
```

では、変換表のバリュー(平文時の文字)に対して、 `replaced_char` でキー(暗号字の文字)を取り出しています。

`text.replace` は引数1つ目の文字を2つ目の文字に変換します。つまり平文時の文字を暗号字の文字に置き換えています。ここでは暗号化済みのテキストを変換したいので、平文時の文字として扱うのは不適切なので誤った選択肢です。

【選択肢2】はどうでしょうか。

```
output = ""
for char in text:
    output += key.get(char, "")
return output
```

textに対して1文字ずつ繰り返し処理をしています。 `key.get` では暗号文の文字をキーにして平文時の文字を取り出しています。それをoutputという文字列に追記しています。text が暗号文で欲しい出力が平文のため、【選択肢2】が正解の選択肢です。

【選択肢3】も見てみましょう。

```
output = ""
for char in text:
    output += key.pop(char, "")
return output
```

【選択肢2】と非常に似ていますが、 `key.pop` な箇所が異なります。popは1度取得したキーを辞書から削除してしまいます。暗号文に同じ文字が2回出ると変換することができないため、誤った選択肢です。

正しい方法で復号化すると「たからは さいの しまに かくした」になります。

果たして海賊団は宝を見つけることはできたのでしょうか。今回は、換字式暗号を題材にして文字列の置換や辞書型の取り扱いを紹介しました。少しでも皆さまのためになりましたら幸いです。

【出題者】
早川 敦士さん
株式会社DATAFLUCTで事業責任者(プロダクトマネージャー)として従事。データと機械学習をビジネスに活かすプロダクトを開発している。また、株式会社ホクソエムで執行役員を務めたり、プログラミング教育に携わる。新卒でリクルートコミュニケーションズに入社しWeb広告やマーケティングオートメーションなどのB2Cマーケティングを経験し、その後ユーザベースにてB2BマーケティングプラットフォームであるFORCASのクローラーやデータ分析基盤を開発するチームリーダーをする。大学在学中に『データサイエンティスト養成読本』(技術評論社刊)を共著にて執筆。その後も『機械学習のための特徴量エンジニアリング』(オライリー・ジャパン刊)や『Pythonによるはじめての機械学習プログラミング』(技術評論社刊)などで執筆活動を続けている。Youtubeチャンネル『データサイエンティストgepuro』で動画を投稿。
・Twitterアカウント