문제
BOJ 3417 - Vigenère Cipher Encryption
비제네르 암호(Vigenère Cipher)는 키 문자열을 반복 사용하여 평문을 암호화하는 고전 암호 방식이다. 키 문자열 s1과 평문 s2가 주어지면, 평문의 각 문자를 키의 해당 위치 문자만큼 알파벳 순서로 이동시켜 암호문을 만든다. 키는 평문 길이에 맞게 반복된다.
입력
- 여러 줄의 입력이 주어지며, 각 줄에 키 문자열
s1과 평문s2가 공백으로 구분되어 주어진다. - 모든 문자는 대문자 알파벳이다.
출력
각 줄마다 암호화된 문자열을 출력한다.
예제
| 입력 | 출력 |
|---|---|
ABC HELLO | HFNLP |
풀이
키 문자열을 인덱스로 순환하면서 평문의 각 문자를 암호화하는 비제네르 암호 구현 문제이다.
- 키
s1과 평문s2를 읽는다. EOF까지 반복한다. - 평문의 각 문자
c에 대해:(c - 'A')+(s1[i] - 'A' + 1)를 26으로 나눈 나머지를 구한다.- 결과에
'A'를 더해 암호화된 문자를 얻는다. - 키 인덱스
i는(i + 1) % s1.length()로 순환한다.
- 암호화된 문자열을 출력하고 줄바꿈한다.
핵심 아이디어: 코드의 이동량 계산식 (c - 65 + (s1[i] - 64)) % 26 + 65를 분석하면, s1[i] - 64는 s1[i] - 'A' + 1이므로 키 문자 'A'는 이동 없음, 'B'는 1칸 이동을 의미한다. 키 인덱스를 % s1.length()로 순환시켜 키를 반복 사용한다.
코드
#include <iostream>
using namespace std;
int main() {
string s1, s2;
while (cin >> s1 >> s2) {
int i(0);
for (char c : s2) {
cout << char((c - 65 + (s1[i] - 64)) % 26 + 65);
i = (i + 1) % s1.length();
}
cout << "\n";
}
}복잡도
- 시간: O(L) — 평문 길이 L만큼 반복
- 공간: O(1) — 추가 자료구조 없이 입력 문자열만 사용