Xorcism

Xorcism

어려움

지침

키에 대한 참조를 담고, 임의의 데이터와 비트 단위 XOR 연산을 하는 스트리밍 어댑터를 작성해요.

XOR은 기본적인 이진 연산이에요. 입력의 각 비트에 대해 두 입력 비트가 다르면 출력의 해당 비트를 1로 설정해요. 두 입력이 모두 1이거나 모두 0이면 출력의 해당 비트는 0이에요.

문서를 키와 XOR할 때는 키를 필요한 만큼 반복해서, 입력 문서와 길이가 같은 출력 문서를 만들어요.

문서를 키와 XOR하는 방법은 1900년대 초반까지도 암호학에 쓰였어요. 데이터를 숨기는 방법으로서는 완전히 구식이지만, 진짜 난수의 복잡함 없이 무작위처럼 보이는 노이즈 데이터를 만들 때는 놀랄 만큼 유용해요. 현대 암호학에서도 특정 암호에는 이따금 쓰이는데, 그 암호 자체는 아주 무작위적이고 무한히 긴 키를 만들어 내는 메커니즘에 불과하고, 이 키를 문서와 XOR하는 거예요.

XOR 암호화의 흥미로운 성질 하나는 대칭적이라는 점이에요. 어떤 수를 자기 자신과 XOR하면 0이 되고, 어떤 수를 0과 XOR하면 입력한 수가 그대로 나와요. 따라서 XOR로 암호화된 문서를 복호화하려면 같은 키로 다시 XOR 암호화하면 돼요.

메모리 할당 없이

구조체가 키를 복사하지 않고 참조를 담고 있는지 확인하는 테스트를 작성하기는 현실적이지 않아요. 마찬가지로 munge나 munge_in_place, 그리고 그 헬퍼 함수들이 힙에 할당하지 않는다는 것을 테스트로 증명하기도 현실적이지 않아요. 그래도 이런 방식으로 풀이를 작성해 보세요.

구현

키에 대한 참조를 담는 struct Xorcism을 작성해야 해요. 이 구조체는 munge_in_place와 munge, 두 가지 메서드를 제공해야 해요. 앞의 메서드는 바이트 버퍼를 제자리에서 수정해요. 뒤의 메서드는 반복자 어댑터로, 임의의 데이터 반복자를 받아서 새로운 데이터 반복자를 반환해요.

이 연습 문제의 스텁 시그니처는 문법은 대부분 맞지만 컴파일되지 않아요. 이 연습 문제의 중요한 목적 중 하나가 라이프타임과 제네릭을 사용하는 데 익숙해지는 것이니까, 시그니처는 직접 채워 넣어야 해요. 또 다른 목표는 두 메서드를 최소한의 중복으로 구현할 수 있는 적절한 분해 방식을 직접 찾아내는 거예요. 헬퍼 함수를 더 추가하는 것을 두려워할 필요는 없어요!

유용한 트레이트

다음 트레이트들이 유용할 거예요:

보너스 테스트

이 연습 문제에는 io 기능 플래그 뒤에 있는 보너스 테스트가 있어요. 이 테스트를 활성화하려면 다음을 실행해요.

cargo test --features io

이 테스트를 위해서는 다음 시그니처를 가진 reader 메서드를 구현해야 해요.

fn reader(self, impl Read) -> impl Read

그리고 다음 시그니처를 가진 writer 메서드도 구현해야 해요.

fn writer(self, impl Write) -> impl Write

이 함수들은 각각 Xorcism 구조체를 알맞은 방향의 스트림 어댑터로 변환해요. 다음 트레이트를 사용해요:

munge 반환값의 수명

impl Trait 기능을 사용하기 때문에 munge 메서드를 구현할 때 수명 관리가 조금 까다로울 수 있어요. 적어도 시작할 때는 Iterator를 구현한 직접 만든 struct를 작성해서 그 구체적인 타입을 반환하는 편이 더 쉬울 거예요. 궁극적으로는 Iterator 콤비네이터를 직접 사용해 해법을 구현해 보는 게 좋아요.


출처

Peter Goodspeed-Niklaus
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Rust Exercism

Xorcism 문제를 시작해 볼 준비가 됐나요?

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