轨道
/
Rust
Rust
/
练习
/
Xorcism
Xorcism

Xorcism

困难

说明

编写一个流式适配器,它包含对某个键的引用,并将该键与任意数据进行按位异或。

异或是一种基本的二进制运算:对于两个输入中的每一位,如果输入位不同,就把输出的对应位设为1。如果两个输入位都是1或都是0,那么输出的对应位就是0。

用键对文档进行异或时,键会被重复任意多次,生成一个长度与输入文档相同的输出文档。

用键对文档进行异或,直到 20 世纪初还被用于密码学。虽然作为隐藏数据的方法,它早已完全过时,但在生成看似随机的噪声数据时却出奇地有用,而且不必处理真正随机性带来的麻烦。在现代密码学的某些密码中,它仍偶尔被用到:密码本身只是一种机制,用来生成一个高度随机、无限长的键,再把这个键与文档做异或。

异或加密有一个有趣的性质:它是对称的。任何数与自身异或都会得到0,而任何数与0异或都会原样返回该数。因此,要解密一份经过异或加密的文档,只需用同一个键再异或加密一次。

不分配内存

要写出一个测试来确保你的 struct 保存的是对键的引用而不是键的副本,并不现实。同样,也无法用测试证明 munge 和 munge_in_place 以及它们的所有辅助函数都没有在堆上分配内存。尽管如此,你还是应该试着按这种方式来编写提交的解答。

实现

你需要编写一个 struct Xorcism,它保存着对某个键的引用。这个 struct 必须提供两个方法:munge_in_place 和 munge。前者就地调整一个字节缓冲区。后者是一个迭代器适配器:它接受任意数据迭代器,并返回一个新的数据迭代器。

本练习中桩代码的签名在语法上基本正确,但它们无法编译:这个练习的很大一部分意义,就是让你熟悉生命周期和泛型的用法,所以你需要自己把它们补全。这个练习的另一个目标,是让你想出合适的拆分方式,使你能用最少的重复劳动实现这两个方法。别怕引入额外的辅助函数!

有用的 trait

这些 trait 会很有用:

附加测试

本练习包含附加测试,它们位于 io 功能标志之后。要启用它们,请运行

cargo test --features io

对于这些测试,你需要实现一个 reader 方法,它的签名是

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

以及一个 writer 方法,它的签名是

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

这两个函数各自把 Xorcism struct 转换成相应方向上的流式适配器。它们用到了这些 trait:

munge返回值的生命周期

由于使用了impl Trait特性,在实现munge方法时,生命周期的管理可能会有点棘手。你可能会发现,自己写一个带有Iterator实现的struct并返回那个具体类型会更容易一些,至少这样能先上手。最后,不妨试着直接用Iterator组合子来实现解答。


来源

Peter Goodspeed-Niklaus
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Rust Exercism

准备好开始 Xorcism 了吗?

注册 Exercism,借助 99 个练习 和真人导师指导,学习并掌握 Rust,全部免费。