차근차근
시저 암호 복호화 - JAVA( + 많은 알파벳 찾기) 본문
어제 만든 시저 암호를 복호화 해보자.
#문제설명
"Fipmizi mr csyvwipj"를 복호화 할 것이다.
1. key 값은 주어지지 않고 암호화 된 메세지 "Fipmizi mr csyvwipj" 만 받는다.
2. 메세지 중에서 가장 많은 알파벳을 찾는다.
("Fipmizi mr csyvwipj"에서 가장 많이 나온 알파벳은 i이다.)
여기서 i는 e를 암호화 한 것으로 본다.
3. i와 e의 차이를 통해 key 값을 구할 수 있다.
4. 암호화된 메세지와 key 값을 통해 복호화를 한다.
(복호화 알고리즘은 저번 포스팅과 동일하다)
결과는 풀이에서 볼 수 있다.
# 풀이
먼저 가장 많은 단어를 찾아야 한다.
public static char maxAlpha(String st) {
int maxCount = 0;
int index = 0;
int[] alpha = new int[26];
st = st.toLowerCase();
//공백 제거
st = st.replace(" ", "");
for(int i=0; i<st.length(); i++) {
char ch = st.charAt(i);
alpha[(ch-'a')]++;
}
for(int i=0; i<26; i++) {
if(maxCount < alpha[i]) {
maxCount = alpha[i];
index = i;
}
}
return (char)('a'+index);
}
알파벳의 수를 담을 26크기의 alpha 배열을 만든다.
받은 문자열을 toLowerCase()로 대소문자 구분이 없게 한다.
(여기서 공백제거를 하지 않으면 java.lang.ArrayIndexOutOfBoundsException라는 에러가 난다.
공백 문자의 아스키 코드가 32이기 때문에 아스키 코드 값이 97인 'a'를 빼면 -65이기 때문이다.)
다음으로는 for문으로 문자열의 요소를 하나씩 받아서 alpha 배열에 해당하는 요소의 인덱스의 값을 1씩 증가시킨다.
alpha 배열에서 가장 값이 높은 인덱스를 찾는다.
return 값이 char이므로 'a'+index 값을 리턴한다.
이제 key값을 찾아보자.

위의 그림에서 보면 암호문의 i와 e는 4의 차이가 난다. 따라서 평문에서 key값을 4를 주면 "Fipmizi mr csyvwipj"이 되는 것이다.
'e' - 'i'를 하면 -4가 나온다. 어제한 암호화 코드는 함수 이름만 바꾸고 복호화에 그대로 쓰기 때문에 key 값을 양수로 바꿔줘야 한다.(음수이면 나머지를 구하는 부분이 복잡해진다.)
i를 e로 바꾸는 방법은 -4도 있지만 계속 더해서 한바퀴를 돌아 e가 되는 방법도 있다.
그래서 음수인 key 값에 알파벳 개수인 26을 더하면 22가 나온다. i를 22번 앞으로 움직이면 e가 되는 것이다.
public static void main(String[] args) {
String msg = "Fipmizi mr csyvwipj";
int key = 'e' - maxAlpha(msg);
if(key < 0) {
key += 26;
}
System.out.println("maxAlpha = " + maxAlpha(msg)); //i
System.out.println("key = " + key); //22
System.out.println("dec : " + Decryption(msg, key)); //dec : Believe in yourself
}
이렇게 key값을 구했으니 암호화 함수를 Decryption으로 이름만 바꾸고 실행하면 "Believe in yourself"가 나온다!
∠( ᐛ 」∠)_
이 엉망진창인 글을 쓰는데만 1시간 넘게 걸렸다.. 다음엔 줄일 수 있기를
'Programming > JAVA' 카테고리의 다른 글
intellij 주석 색깔 변경하는 방법 (0) | 2022.10.06 |
---|---|
선택 정렬 - 자바[JAVA] (0) | 2022.06.23 |
시저 암호(Caesar Cipher) - JAVA (0) | 2022.04.29 |