TechCraft – エンジニアのためのスキルアップメモ

エンジニアのスキルアップを少しでも加速する技術ブログ

ビジュネル暗号入門:仕組みとPythonによる実装解説

ビジュネル暗号入門:仕組みとPythonによる実装解説

1. はじめに

暗号技術の歴史において、ビジュネル暗号(Vigenère Cipher)は多表換字式暗号の代表例として知られています。16世紀に考案され、19世紀まで解読困難とされていたこの暗号方式は、シーザー暗号の弱点を克服するために開発されました。

本記事では、ビジュネル暗号の基本的な仕組みを解説し、Pythonによる実装方法を紹介します。暗号の基礎を学びたい初心者の方にとって、実践的なステップバイステップのガイドとなることを目指します。

2. ビジュネル暗号の仕組み

ビジュネル暗号は、アルファベットの文字を一定の規則で置き換える換字式暗号の一種です。特徴的なのは、単一のシフト量ではなく、キーワードに基づいて複数のシフト量を用いる点です。

2.1 ビジュネル方陣(Vigenère Square)

ビジュネル暗号では、以下のような26×26のアルファベット表(ビジュネル方陣)を使用します。

ビジュネル方陣

この表では、各行がアルファベットを1文字ずつシフトしたものになっています。暗号化の際は、平文の文字と鍵の文字を使って、この表から対応する暗号文の文字を取得します。

2.2 暗号化の手順

  1. 平文と鍵を用意する:例えば、平文がHELLO、鍵がKEYとします。
  2. 鍵を平文の長さに合わせて繰り返すKEYKE
  3. 各文字をビジュネル方陣で変換する
    • 平文の1文字目Hと鍵の1文字目Kを使い、ビジュネル方陣KH列の文字を取得(R)。
    • 同様に、EEILYJLKVOES
  4. 暗号文を得るRIJVS

2.3 復号化の手順

復号化は、暗号化の逆の手順を踏みます。ビジュネル方陣を使って、暗号文の文字と鍵の文字から平文の文字を特定します。

3. Pythonによる実装

ビジュネル暗号をPythonで実装することで、仕組みの理解を深めることができます。以下に、暗号化と復号化の関数を示します。

import string

ALPHABET = string.ascii_uppercase
ALPHABET_SIZE = len(ALPHABET)

def generate_key(message: str, keyword: str) -> str:
    key = keyword
    while len(key) < len(message):
        key += keyword
    return key[:len(message)]

def encrypt(message: str, keyword: str) -> str:
    message = message.upper()
    keyword = keyword.upper()
    key = generate_key(message, keyword)
    cipher_text = ''
    for m_char, k_char in zip(message, key):
        if m_char in ALPHABET:
            m_index = ALPHABET.index(m_char)
            k_index = ALPHABET.index(k_char)
            c_index = (m_index + k_index) % ALPHABET_SIZE
            cipher_text += ALPHABET[c_index]
        else:
            cipher_text += m_char
    return cipher_text

def decrypt(cipher_text: str, keyword: str) -> str:
    cipher_text = cipher_text.upper()
    keyword = keyword.upper()
    key = generate_key(cipher_text, keyword)
    original_text = ''
    for c_char, k_char in zip(cipher_text, key):
        if c_char in ALPHABET:
            c_index = ALPHABET.index(c_char)
            k_index = ALPHABET.index(k_char)
            m_index = (c_index - k_index + ALPHABET_SIZE) % ALPHABET_SIZE
            original_text += ALPHABET[m_index]
        else:
            original_text += c_char
    return original_text

使用例

message = "HELLO WORLD"
keyword = "KEY"

encrypted = encrypt(message, keyword)
print(f"Encrypted: {encrypted}")

decrypted = decrypt(encrypted, keyword)
print(f"Decrypted: {decrypted}")

出力:

Encrypted: RIJVS UYVJN
Decrypted: HELLO WORLD

4. 注意点と応用

4.1 鍵の選び方

鍵はできるだけ長く、ランダムな文字列が望ましいです。短い鍵や意味のある単語を鍵にすると、頻度分析などの手法で解読されやすくなります。

4.2 非アルファベット文字の扱い

上記の実装では、アルファベット以外の文字(スペースや記号など)はそのまま出力しています。必要に応じて、これらの文字も処理するように実装を変更できます。

4.3 小文字の扱い

現在の実装では、すべて大文字に変換して処理しています。小文字を区別したい場合は、アルファベットのリストを拡張し、対応する処理を追加する必要があります。

5. まとめ

ビジュネル暗号は、シーザー暗号の弱点を克服するために開発された多表換字式暗号であり、暗号技術の発展に大きく寄与しました。Pythonによる実装を通じて、その仕組みを理解することができます。

暗号技術の学習は、情報セキュリティの基礎を築く上で重要です。ビジュネル暗号を入り口として、より高度な暗号方式や現代の暗号技術にも興味を持っていただければ幸いです。

6. 参考文献

参考書籍