본문 바로가기

백준/JAVA

[Baekjoon/JAVA] 1718번 - 암호

Baekjoon Online Judge

문제로 이동

 

문제

Vigenere cipher이라는 암호화 방법은 암호화하려는 문장 (평문)의 단어와 암호화 키를 숫자로 바꾼 다음, 평문의 단어에 해당하는 숫자에 암호 키에 해당하는 숫자를 더하는 방식이다. 이 방법을 변형하여 평문의 단어에 암호화 키에 해당하는 숫자를 빼서 암호화하는 방식을 생각해 보자.

예를 들어 암호화 키가 love이고, 암호화할 문장이 “nice day” 라면 다음과 같이 암호화가 이루어진다.

제시된 평문의 첫 번째 문자인 ‘n’은 해당 암호화 키 ‘l’의 알파벳 순서가 12 이므로 알파벳상의 순서에서 ‘n’보다 12앞의 문자인 ‘b’로 변형된다.

변형된 문자가 ‘a' 이전의 문자가 되면 알파벳 상에서 맨 뒤로 순서를 돌린다. 예를 들면 평문의 세 번째 문자인‘c’는 알파벳 상에서 3 번째이고 대응하는 암호화키 ‘v'는 알파벳 순서 22로 ‘c'에서 22 앞으로 당기면 ‘a'보다 훨씬 앞의 문자이어야 하는데, ‘a’앞의 문자가 없으므로 ‘z’로 돌아가 반복되어 ‘g’가 된다. 즉 평문의 문자를 암호화키의 문자가 알파벳 상에서 차지하는 순서만큼 앞으로 뺀 것으로 암호화한다.

평문의 문자가 공백 문자인 경우는 그 공백 문자를 그대로 출력한다.

이와 같은 암호화를 행하는 프로그램을 작성하시오.

 

입력

첫째 줄에 평문이, 둘째 줄에 암호화 키가 주어진다.

평문은 알파벳 소문자와 공백문자(space)로만 구성되며, 암호화 키는 알파벳 소문자만으로 구성된다. 평문의 길이는 공백까지 포함해서 30000자 이하이다.

 

출력

첫 번째 줄에 암호문을 출력한다.

 


예제 입력 예제 출력
nice day
love
btgz oet

풀이

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        String s = in.nextLine(); // 평문
        String code = in.next(); // 암호화 키

        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ')
                System.out.printf(" ");
            else {
                // 변형된 문자의 순서
                int n = s.charAt(i) - code.charAt(i % code.length()) - 1;

                if (n < 0) n += 26; // 변형된 문자가 a 이전의 문자일 경우

                System.out.printf((char)(n % 26 + 'a') + "");
            }
        }
    }
}

문자열의 각 문자를 암호화 키의 문자로 빼서 변형된 문자의 알파벳상 순서(n)를 구했다. 알파벳 순서의 시작을 0으로 잡았기 때문에 -1을 해줬다.

만약 n이 0보다 작다면 26을 더해서 알파벳 맨 뒤부터 몇 번째인지를 구했다.

출력할 때 % 26을 코드에 추가했는데, 이는 n이 25(마지막 알파벳의 순서)보다 커지는 것을 막기 위함이다.

'백준 > JAVA' 카테고리의 다른 글

[Baekjoon/JAVA] 1855번 - 암호  (0) 2023.01.23
[Baekjoon/JAVA] 1731번 - 추론  (0) 2023.01.22
[Baekjoon/JAVA] 1681번 - 줄 세우기  (0) 2023.01.20
[Baekjoon/JAVA] 1673번 - 치킨 쿠폰  (0) 2023.01.19
[Baekjoon/JAVA] 15829번 - Hashing  (0) 2023.01.18