Pythonでヴィジュネル(Vigenère)暗号を使って文字列を暗号化する方法
問題の概要
小文字アルファベットのみで構成された文字列 text と、もう一つの文字列 key が与えられたとします。このとき、text の各文字 text[i] を、key[i] が表すオフセット分だけ右へずらした新しい文字列を作成します。ここでのオフセットとは、key[i] のアルファベット上の位置(a=0、b=1、c=2 …)のことです。ずらした結果が「z」を超えた場合は、先頭の「a」に戻って折り返します。これは古典暗号の一つであるヴィジュネル暗号(Vigenère cipher)として知られる方式です。
例えば、入力が text = "code"、key = "team" の場合、出力は "vsdq" となります。
計算例:「code」と「team」の場合
実際にどのように変換されるか見てみましょう。
- c(2) + t(19) = 21 → v
- o(14) + e(4) = 18 → s
- d(3) + a(0) = 3 → d
- e(4) + m(12) = 16 → q
この結果、「code」は「vsdq」へと暗号化されます。
解決のための手順
この問題は次のステップで解くことができます。
- 結果を格納するための空リスト cip を用意する
- start に文字 'a' の ASCII コード(97)を代入する
- text と key から zip() でそれぞれ文字 l、k を同時に取り出し、以下を繰り返す
- shift := ord(k) − start …… 鍵文字によるシフト量を計算
- pos := start + ((ord(l) − start + shift) mod 26) …… 26 で剰余を取ることで z を超えた場合の折り返しを処理
- pos に対応する文字を cip の末尾に追加する
- cip 内のすべての文字を連結して返す
Pythonでの実装例
class Solution:
def solve(self, text, key):
cip = []
start = ord('a')
for l, k in zip(text, key):
shift = ord(k) - start
pos = start + (ord(l) - start + shift) % 26
cip.append(chr(pos))
return ''.join([l for l in cip])
ob = Solution()
text = "code"
key = "team"
print(ob.solve(text, key))
入力
"code", "team"
出力
vsdq
コードのポイント
- zip(text, key):平文と鍵の文字をペアごとに効率よく取り出せます。
- ord() / chr():文字と ASCII コードを相互に変換し、数値としてシフト計算を行います。
- % 26:アルファベットが26文字であることを利用した剰余演算により、端から端への折り返し(ラップアラウンド)を自然に実現しています。
このように、わずか数行のコードでヴィジュネル暗号による暗号化を実装できます。復号を行う場合は、シフト量を逆方向(減算)に適用することで元の文字列を復元できます。
-
Pythonで%演算子を使った文字列フォーマットの基本と使い方
Pythonでは、文字列を整形(フォーマット)するために複数の方法が用意されています。主な方法は以下の3つです。% 演算子を使う方法{} (formatメソッドやf文字列)を使う方法Template文字列を使う方法この記事では、その中でも「%」を使った文字列フォーマットについて詳しく解説します。文字列フォーマットの2つの方式Pythonの文字列フォーマットには、大きく分けて以下の2つの方式があります。文字列フォーマット式:C言語のprintfスタイルに基づいた方法(%演算子)文字列フォーマットメソッド呼び出し:Python 2.6以降で利用可能なstr.format()メソッドなど%フォーマッ
-
Pythonでsetを使って文字列内の母音の数をカウントするプログラム
この記事では、ユーザーが入力した文字列に含まれる母音の数をカウントするPythonプログラムを紹介します。ポイントとなるのはPythonのset(セット)の活用です。setとは、反復可能(iterable)で可変(mutable)、かつ重複する要素を持たないという特徴をもつ、順序なしのコレクションデータ型です。 実行例 入力:str1 = pythonprogram 出力:3 アルゴリズム ステップ1:まず、文字列内の母音を数えるためのカウンター変数を用意します。 ステップ2:母音のセットを作成します。 ステップ3:与えられた文字列内のすべての文字を順番に走査します。 ステップ4:文字が