KnowHow

技術的なメモを中心にまとめます。
検索にて調べることができます。

pythonコードのデバックテクニックメモ

登録日 :2024/01/29 05:03
カテゴリ :Python基礎

Vigenère 暗号を用いて、メッセージ(アルファベット)を変換(暗号化する)ためのプログラムサンプルを記述していて、以下のようなエラーが出てしまいました。

index = (ALPHABET.index(char) + ALPHABET.index(key[i])) % len(ALPHABET)
ValueError: substring not found

ValueError: substring not found エラーは、ALPHABET.index(char) や ALPHABET.index(key[i]) のいずれかが指定されたサブストリング(部分文字列)を見つけることができない場合に発生します。

  • ALPHABETに含まれない文字が char や key[i] に含まれていないかを確認します。
  • ALPHABETの内容が正しく設定されていることを確認します。string.ascii_uppercaseは通常、AからZまでのアルファベットを含むはずです。

デバッグのために、エラーが発生する前に、char や key[i] の値を出力してみることで、具体的なエラーの原因を特定しやすくなります。例えば、以下のように出力文を追加してみてください:

for i, char in enumerate(message):
    if char not in ALPHABET:
        result += char
        continue

    try:
        char_index = ALPHABET.index(char)
        key_index = ALPHABET.index(key[i])
        index = (char_index + key_index) % len(ALPHABET)
        result += ALPHABET[index]
    except ValueError as e:
        print(f"Error: {e}, char: {char}, key[i]: {key[i]}")

これにより、エラーが発生する具体的な文字やキーが表示され、それがなぜ問題となっているかがわかるようになります。

結果として

HELL0HELL0HELL0HELL0H
Error: substring not found, char: C, key[i]: 0
Error: substring not found, char: L, key[i]: 0
Error: substring not found, char: E, key[i]: 0
ATTACK SILICON VALLEY

これは、エラーの原因は、keyに数字(0)が含まれており、ALPHABETには数字が含まれていないためです。Vigenère 暗号のキーは通常アルファベットのみを含むものであるため、数字がキーに含まれると ALPHABET.index(key[i]) で ValueError が発生します。

解決策としては、数字などのアルファベット以外の文字をキーに含めないようにするか、含める場合は事前にチェックするなどの処理を追加することが考えられます。

修正例として、キーに数字が含まれる場合は特別な処理を行うようにしたコードを以下に示します。

import string

ALPHABET = string.ascii_uppercase

def generate_key(message: str, keyword: str) -> str:
    key = keyword
    remain_length = len(message) - len(keyword)
    for i in range(remain_length):
        key += key[i]
    return key

def encrypt(message: str, key: str) -> str:
    result = ''
    for i, char in enumerate(message):
        if char not in ALPHABET:
            result += char
            continue

        try:
            char_index = ALPHABET.index(char)
            key_char = key[i].upper()

            if key_char not in ALPHABET:
                # 数字などがキーに含まれる場合の処理
                # ここではそのまま追加するが、適切な処理を追加してください
                result += key_char
            else:
                key_index = ALPHABET.index(key_char)
                index = (char_index + key_index) % len(ALPHABET)
                result += ALPHABET[index]
        except ValueError as e:
            print(f"Error: {e}, char: {char}, key[i]: {key[i]}")

    return result

if __name__ == '__main__':
    kw = 'HELL0' #ここが問題。「O」を「0」にしてしまった。
    m = 'THIS IS ENCODE TEST'
    k = generate_key(m, kw)
    print(k)
    e = encrypt(m, k)
    print(e)