0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2023-05-11

はじめに

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

実装

caesar_cipher
# asciiの文字を使えるようにする
import string

# 文字列を暗号化する関数
def caesar_cipher(text: str, shift: int) -> str:
    # シフト後の文字を入れる変数
    result = ""
    # 一つ一つの文字を取ってくる
    for char in text:
        # 大文字の場合
        if char.isupper():
            # 大文字のアルファベット26文字を表示
            alphabet = string.ascii_uppercase
        # 小文字の場合
        elif char.islower():
            # 小文字のアルファベット26文字を表示
            alphabet = string.ascii_lowercase
        # アルファベットでない場合
        else:
            # 取り出した1文字をresultに加える
            result += char
            # 次のループに行く
            continue

        # 取り出したアルファベットを3つ分シフトした時の文字のインデックスを取得(x,y,zの時にエラーにならないように、全体のアルファベット数(26)で割った時の余りをインデックスとする)
        index = (alphabet.index(char) + shift) % len(alphabet)
        # 取得したインデックスに対応するアルファベットをresultに追加
        result += alphabet[index]
    # 結果を返す
    return result

# テスト
if __name__ == "__main__":
    print(caesar_cipher("animal", 3))

stringモジュールを使わない場合の実装だと以下のように実装できる。
総当りで文字列をシフトさせたパターンを表示させる関数(caesar_cipher_hack)についても追記。

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)

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?