카이사르 암호 같은 간단한 이동 암호와, 더 안전한 치환 암호를 만들어 보세요.
"그가 남에게 알릴 비밀스러운 일이 있으면 암호로 적었는데, 곧 알파벳 글자들의 순서를 바꿔서 어떤 단어도 알아볼 수 없게 만들었다. 누군가 이것을 해독해서 그 뜻을 알고자 한다면, 알파벳의 네 번째 글자인 D를 A 대신에 넣고, 나머지 글자들도 그렇게 해야 한다." 수에토니우스, 《율리우스 카이사르의 생애》에서
암호는 텍스트를 읽기 어렵게 만들면서도 여전히 쉽게 해독할 수 있게 해 주는 아주 단순한 알고리즘이에요. 암호는 여러 가지 형태의 암호 분석에 취약하지만, 카이사르는 적들이 암호 분석가가 아니었다는 점에서 운이 좋았어요.
카이사르 암호는 율리우스 카이사르가 전장에 보낸 몇몇 메시지에 쓰였어요. 카이사르는 그 암호가 그다지 좋지 않다는 걸 알고 있었지만, 그 점에서 든든한 편이 하나 있었어요. 바로 거의 아무도 글을 잘 읽지 못했다는 거예요. 그래서 몇 글자쯤 어긋나도, 사람들이 겨우 아는 몇 단어를 알아보지 못하게 하기에는 충분했어요.
이번 과제는 카이사르 암호 같은 간단한 이동 암호를 만드는 거예요. 다음 그림은 카이사르 암호를 잘 보여주는 예예요:
![]()
예를 들어볼게요:
"iamapandabear"를 encode 함수에 입력하면 암호 "ldpdsdqgdehdu"가 반환돼요. 전송 중에 메시지를 비밀로 지키기에는 충분할 만큼 알아보기 어려워요.
"ldpdsdqgdehdu"를 decode 함수에 넣으면 원래의 "iamapandabear"가 반환돼서, 친구가 원래 메시지를 읽을 수 있어요.
이동 암호는 상대편 지휘관이 원리를 알아내면 금세 쓸모가 없어져요. 그래서 대신 치환 암호를 써볼까요? 코드를 고쳐서 키를 지정하고, 그 키를 이동 거리로 사용할 수 있게 해봐요.
예를 들어볼게요:
키가 "aaaaaaaaaaaaaaaaaa"일 때 문자열 "iamapandabear"를 인코딩하면 원래의 "iamapandabear"가 반환돼요.
키가 "ddddddddddddddddd"일 때 "iamapandabear"를 인코딩하면 알아보기 어려운 "ldpdsdqgdehdu"가 반환돼요.
위 예에서는 키 값으로 a = 0을 잡았어요. 그래서 평문에 키를 더하면 결국 같은 메시지가 나와요. 그래서 "aaaa"는 이상적인 키가 아니에요. 하지만 키를 "dddd"로 잡으면 카이사르 암호와 같은 결과가 나와요.
어떤 암호든 가장 약한 고리는 사람이에요. 무작위 값을 제공하고 키에 소문자만 들어가도록 해서, 치환 암호를 조금 더 오류에 강하게 만들어봐요.
누군가 키를 아예 제출하지 않으면, 소문자 100자 이상으로 된 진짜 무작위 키를 만들어요.
이동 암호는 텍스트를 조금 이상하게 만들어서 동작하지만, 빈도 분석에 취약해요. 치환 암호는 그 점을 보완해 주지만, 키가 짧거나 공백이 그대로 남아 있으면 여전히 아주 취약해요. 나중에 "crypto-square" 연습 문제에서 이 문제를 해결하는 방법 하나를 보게 될 거예요.
이 분야에서 더 나아가고 싶다면, 안전하게 키를 주고받으려면 어떻게 해야 하는지가 궁금해지기 시작할 거예요. 이 방식이 처음 구현된 사례 하나는 위키백과의 Diffie-Hellman에서 살펴볼 수 있어요.
인덱스가 범위를 넘어갈 때는 모듈로 같은 산술 연산을 사용해 인덱스를 감싸봐요. Character와 String 클래스도 좋은 친구가 되어줘요.