트랙
/
Python
Python
/
연습 문제
/
간단한 암호
간단한 암호

간단한 암호

쉬움

지침

비즈네르 암호를 구현해 봐요. 비즈네르 암호는 간단한 치환 암호예요.

암호 용어

암호는 문자열을 암호화, 즉 인코딩하는 데 사용하는 알고리즘이에요. 암호화되지 않은 문자열을 _평문_이라고 하고, 암호화된 문자열을 _암호문_이라고 해요. 평문을 암호문으로 바꾸는 것을 _인코딩_이라고 하고, 그 반대를 _디코딩_이라고 해요.

_치환 암호_에서는 평문의 각 글자가 _키_의 도움을 받아 계산된 암호문 글자로 바뀌어요. (바뀐 글자가 원래 글자와 같을 수도 있어요.)

인코딩 세부 사항

이 암호에서 키는 "abcd"처럼 소문자 여러 개로 이루어진 문자열이에요. 평문의 각 글자는 키의 해당 글자에 따라 정해지는 거리만큼 _이동_하거나 _회전_해요. 키에서 "a"는 0만큼 이동한다는 뜻이에요(즉, 이동하지 않아요). 키에서 "b"는 1만큼 이동한다는 뜻이에요. 키에서 "c"는 2만큼 이동한다는 뜻이고, 이런 식이에요.

평문의 첫 번째 글자에는 키의 첫 번째 글자를 사용하고, 두 번째 글자에는 키의 두 번째 글자를 사용하는 식이에요. 평문이 끝나기 전에 키의 글자를 다 써버리면 키의 처음으로 돌아가서 다시 사용해요.

키가 "dddddd"처럼 한 글자로만 이루어져 있다면 평문의 모든 글자가 같은 거리만큼(이 예에서는 3만큼) 이동해요. 이 경우 회전 암호나 이동 암호(시저 암호라고도 해요)와 같아져요. 예를 들어 평문 "iamapandabear"는 "ldpdsdqgdehdu"가 돼요.

키가 "a"만(한 번 이상) 포함한다면 이동 거리가 0이라서 암호문이 평문과 같아요.

그런데 보통은 키가 이보다 더 복잡해요! 키가 "abcd"라면 평문의 글자들은 0, 1, 2, 3만큼 이동해요. 평문이 "hello"라면 5번 이동해야 하므로 키가 다시 처음으로 돌아가서, 이동 거리는 0, 1, 2, 3, 0이 돼요. 이 이동 거리들을 "hello"의 글자들에 적용하면 "hfnoo"가 돼요.

무작위 키

키가 주어지지 않으면 라틴 알파벳의 무작위 소문자 100개 이상으로 이루어진 키를 만들어요.

여기서는 random과 secrets 중 무엇을 써야 할까요?

Python 3.6부터는 "난수"를 만들어 내는 서로 다른 두 모듈이 있어요.

random이라는 모듈은 의사 난수예요. 즉, 진정한 난수를 만들어 내는 것이 아니라, 난수를 흉내 내는 알고리즘을 따를 뿐이에요. 이렇게 만들어진 "난수"는 이미 알려진 알고리즘을 통해 만들어지기 때문에 진정한 난수가 아니에요. 그래서 random 모듈은 암호학에 적합하지 않고, 사용해서도 안 돼요. 바로 의사 난수이기 때문이에요.

secrets라는 모듈은 암호학적으로 강력한 "난수"를 만들어 내서, 암호학에 필요한 더 강한 보안을 제공해요. 엄밀히 말하면 이 난수도 의사 난수예요. 하지만 이 모듈이 만들어 내는 숫자는 절대 예측할 수 없다는 보장이 있어요.

이건 연습 문제일 뿐이니까 random 모듈을 써도 괜찮아요. 다만 실제로 암호학에 사용하면 매우 안전하지 않을 거라는 점은 기억해 두세요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Python Exercism

간단한 암호 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Python 트랙을 개념 17개연습 문제 146개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.