Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬으로 구현하는 비제네르(Vigenère) 암호: 문자열 암호화 프로그램

비제네르(Vigenère) 암호란?

비제네르 암호는 16세기부터 알려진 고전적인 다중 알파벳 치환 암호입니다. 모든 문자를 동일한 값만큼 밀어내는 카이사르 암호와 달리, 키(key) 문자열의 각 문자가 알파벳에서 차지하는 위치(A=0, B=1, ..., Z=25)를 개별 시프트 값으로 사용합니다. 이 글에서는 파이썬으로 비제네르 방식의 문자열 암호화 프로그램을 직접 구현해 보겠습니다.

문제 정의

소문자 알파벳으로 이루어진 문자열 text와 키 문자열 key가 주어져 있다고 가정합시다. 우리가 구해야 할 것은 text의 각 문자를 key의 대응 문자가 나타내는 오프셋만큼 오른쪽으로 민 새로운 문자열입니다. 만약 문자가 z를 넘어 범위를 벗어나면, 반대편(a)부터 다시 이어지도록 순환(wrap-around) 처리해야 합니다.

예를 들어 text = "code", key = "team"이 입력되면 출력은 "vsdq"가 됩니다.

예시 동작 과정

  • c(2) + t(19) = 21 → v
  • o(14) + e(4) = 18 → s
  • d(3) + a(0) = 3 → d
  • e(4) + m(12) = 16 → q

알고리즘 접근 방법

이 문제는 다음 단계를 따라 해결할 수 있습니다.

  1. 결과를 저장할 새로운 리스트 cip를 생성합니다.
  2. start에 소문자 'a'의 ASCII 코드 값(97)을 저장합니다.
  3. zip()으로 text의 각 문자 lkey의 각 문자 k를 하나씩 짝지어 반복합니다.
    • shift = k의 ASCII 값 − start (키 문자의 알파벳상 위치)
    • pos = start + ((l의 ASCII 값 − start + shift) mod 26)
    • chr(pos)로 변환한 문자를 cip의 끝에 추가합니다.
  4. cip에 담긴 문자들을 하나의 문자열로 연결하여 반환합니다.

여기서 mod 26 연산이 핵심입니다. 시프트 후 알파벳 범위(0~25)를 초과한 값을 다시 처음 위치로 되돌려, 알파벳이 순환하는 구조를 만들어 줍니다.

파이썬 구현 예제

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

복잡도 및 참고 사항

  • 시간 복잡도: O(n) — 문자열 길이에 비례하여 한 번씩 순회합니다.
  • 공간 복잡도: O(n) — 결과 문자를 저장할 리스트가 필요합니다.
  • zip()은 두 문자열 중 더 짧은 길이까지만 반복합니다. 실제 비제네르 암호처럼 keytext보다 짧은 경우에는 (key * (len(text) // len(key) + 1))[:len(text)]와 같이 키를 반복해 늘린 뒤 적용하는 것이 좋습니다.