🗂

【Python】シーザー暗号の実装

2023/05/13に公開

はじめに

シーザー暗号:入力されたアルファベットを3つシフトさせて暗号化する方法。
(例)art → duw

実装

caesar_cipher(not_use_stringModule)
# 文字列を暗号化する関数(stringモジュールを使わない場合)
from typing import Generator, Tuple

def caesar_cipher(text: str, shift: int) -> str:
    result = ""
    len_alphabet = ord("Z") - ord("A") + 1
    for char in text:
        if char.isupper():
            result += chr((ord(char) + shift - ord("A")) %
                          len_alphabet + ord("A"))
        elif char.islower():
            result += chr((ord(char) + shift - ord("a")) %
                          len_alphabet + ord("a"))
        else:
            result += char
    return result

# 解読用の関数(すべてのシフトしたパターンを表示させる)
def caesar_cipher_hack(text: str) -> Generator[Tuple[int: str], None, None]:
    # アルファベットの長さを取得する(stringモジュールが使えない場合)
    len_alphabet = ord("Z") - ord("A") + 1
    for candidate_shift in range(1, len_alphabet + 1):
        reverted = ""
        for char in text:
            if char.isupper():
                index = ord(char) - candidate_shift
                if index < ord("A"):
                    index += len_alphabet
                reverted += chr(index)
            elif char.islower():
                index = ord(char) - candidate_shift
                if index < ord("a"):
                    index += len_alphabet
                reverted += chr(index)
            else:
                reverted += char
        yield candidate_shift, reverted

# テスト
if __name__ == "__main__":
    print("暗号化したもの:" + caesar_cipher("Programming practice", 3))
    # デクリプト(復号化)
    e = caesar_cipher("Programming practice", 3)
    print("復号化したもの:" + caesar_cipher(e, -3))

    # 総当たりでパターンを表示させる。
    for shift_num, decrypted in caesar_cipher_hack(e):
        print(f"{shift_num:2d}", decrypted)

参考

https://www.udemy.com/course/python-algo

Discussion