背景
言語処理100本ノック 2015を今やっているのでその備忘録的なやつ。
やりたいこと
与えられた文字列の各文字を以下の仕様で変換する関数cipherを実装する。
- 英小文字ならば(219 - 文字コード)の文字に置換
- その他の文字はそのまま出力
この関数を用い、英語のメッセージを暗号化・復号化する。
結果
▼ 関数cipher
def cipher (sentense): # 変数を用意 sentenseList = [] result = '' for i in range (0, len(sentense)): # i番目の文字が小文字の場合 if sentense[i].islower(): # リストのi番目にアスキーコード(219-アスキーコード)に対応する文字を挿入 sentenseList.insert(i, chr(219-ord(sentense[i]))) # i番目の文字が小文字ではない場合そのままリストに挿入 else: sentenseList.insert(i, sentense[i]) # リストを文字列に戻す for ii in range (0, len(sentense)): result += sentenseList[ii] #文字列を返す return result
▼ 実行結果
> sentense = "I Am An Engineer." > txt = cipher(sentense) > txt > 'I An Am Emtrmvvi.' > cipher(txt) > 'I Am An Engineer.'
解説/考察
リストを作成して文字数(i)回for文を回してリストに文字列のi番目の文字をリストのi番目に挿入しています。
for i in range (0, len(文字列)): リスト.insert(i, 文字列[i])
挿入の際にi番目の文字が小文字かどうかをif文で条件分岐させています。
if 文字列[i].islower(): # i番目が小文字の場合の処理 else: # i番目が小文字ではない場合の処理
小文字の場合は、文字をアスキーコードに変換し ”219 - アスキーコード” の計算をおこない得た数字を再度文字に戻してリストに挿入します。
暗号化した文字をもとに戻す場合も同様の処理をおこなえば問題なしです。
リスト.insert(i, chr(219-ord(文字列[i])))
文字を暗号化する一連の流れを確認するとこんな感じ。
> ord('a') > 97 > 219-97 > 122 > chr(122) > 'z' > ord('z') > 122 > 219-122 > 97 > chr(97) > 'a'
最後に変換したリスト内の各文字を1つの文字列に戻す作業です。
最初に分解したときと逆のことをやっているだけ。
for ii in range (0, len(文字列)): 新文字列 += リスト[ii]
ちなみに最初に作成したときは、暗号化と復号化の関数を別々に用意して、関数内で以下のように計算をしていました。
# 暗号化 リスト.insert(i, chr(219-ord(文字列[i]))) # 復号化 リスト.insert(i, chr(219+ord(文字列[i])))
結果、わけわからない文字列が返ってきて失敗しました。
安直な考えで引いたのだから足せばいいやろ!と思ったのですがアホですね。
原因は上でやったように一連の流れを追うとわかります。
> ord('a') > 97 > 219-97 > 122 > chr(122) > 'z' > ord('z') > 122 > 219+122 > 341 > chr(341) > 'ŕ'
まあ、わざわざやるまでもないですが。笑