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

간단한 암호

쉬움

지침

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

암호 용어

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

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

인코딩 세부 사항

이 암호에서 키는 "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개 이상으로 이루어진 키를 만들어요.

구현 참고 사항

Cipher 인터페이스의 정의는 cipher.go에 있어요.

구현은 Cipher 인터페이스를 따라야 해요.

type Cipher interface {
    Encode(string) string
    Decode(string) string
}

Encode는 문자열에서 A-Za-z가 아닌 모든 값은 무시해요. 이런 값은 출력에 나타나지 않아요. 출력은 소문자로 정규화돼요.

암호를 얻는 데 사용하는 함수는 다음과 같아요:

func NewCaesar() Cipher { }

func NewShift(distance int) Cipher { }

func NewVigenere(key string) Cipher { }

NewShift의 인자는 1에서 25 또는 -1에서 -25 범위여야 해요. 0은 허용되지 않아요. 인자가 유효하지 않으면 NewShift는 nil을 반환해요.

NewVigenere의 인자는 소문자 a-z로만 이루어져야 해요. 문자 'a'로만 이루어진 값은 허용되지 않아요. 인자가 유효하지 않으면 NewVigenere는 nil을 반환해요.

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

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

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