본문 바로가기
알고리즘 문제 풀이/백준

백준 1718 암호 kotlin (문자열)

by 옹구스투스 2022. 10. 7.
반응형

문제 출처 : https://www.acmicpc.net/problem/1718

 

1718번: 암호

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

www.acmicpc.net

문제

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

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

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

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

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

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

입력

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

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

출력

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

알고리즘 분류

풀이

간단한 문자열 문제.

우선 소문자 알파벳은 총 26개다.

이를 이용하면 한 줄로 암호화 로직을 짤 수 있다.

line = 평문

password = 암호화 키라 할 때,

line[i] - 'a' == line[i]가 몇 번째 알파벳인지

password[i] - 'a' == password[i]가 몇 번째 알파벳인지

단, 문자가 'a'라면 0번째 알파벳이라고 나오기 때문에 +1을 해주어서 1번째 알파벳이라 해주자.

그러면 line[i]가 'a'이고, password[i]가 'a'면 'a'에서 1만큼 땡겨야 하므로 'z'가 된다.

이를 식으로 표현하면

(line[i]-'a') - (password[i%password.length] - 'a' + 1)

음수가 나오는 경우를 방지하기 위해 26을 더해주고, 최종 값에 26 나머지 연산을 하면 암호화 이후의 최종 문자의 인덱스가 나온다.

여기에 'a'를 더하면 우리가 찾는 암호화 문자를 얻을 수 있다.

그러면 다음과 같은 식이 나온다.

Char((26 + (line[i]-'a') - (password[i%password.length] - 'a' + 1)) + 'a'.code)

코드

val br = System.`in`.bufferedReader()

fun main() = with(System.out.bufferedWriter()){
    val line = StringBuilder(br.readLine())
    val password = br.readLine()
    for(i in line.indices){
        if(line[i]==' ')continue
        line[i] = Char(((26+(line[i]-'a')-(password[i%password.length]-'a'+1))%26)+'a'.code)
    }
    write(line.toString())
    close()
}
반응형

댓글