解答

  1. use std::io::Read;
  2. struct RotDecoder<R: Read> {
  3. input: R,
  4. rot: u8,
  5. }
  6. impl<R: Read> Read for RotDecoder<R> {
  7. fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
  8. let size = self.input.read(buf)?;
  9. for b in &mut buf[..size] {
  10. if b.is_ascii_alphabetic() {
  11. let base = if b.is_ascii_uppercase() { 'A' } else { 'a' } as u8;
  12. *b = (*b - base + self.rot) % 26 + base;
  13. }
  14. }
  15. Ok(size)
  16. }
  17. }
  18. fn main() {
  19. let mut rot =
  20. RotDecoder { input: "Gb trg gb gur bgure fvqr!".as_bytes(), rot: 13 };
  21. let mut result = String::new();
  22. rot.read_to_string(&mut result).unwrap();
  23. println!("{}", result);
  24. }
  25. #[cfg(test)]
  26. mod test {
  27. use super::*;
  28. #[test]
  29. fn joke() {
  30. let mut rot =
  31. RotDecoder { input: "Gb trg gb gur bgure fvqr!".as_bytes(), rot: 13 };
  32. let mut result = String::new();
  33. rot.read_to_string(&mut result).unwrap();
  34. assert_eq!(&result, "To get to the other side!");
  35. }
  36. #[test]
  37. fn binary() {
  38. let input: Vec<u8> = (0..=255u8).collect();
  39. let mut rot = RotDecoder::<&[u8]> { input: input.as_ref(), rot: 13 };
  40. let mut buf = [0u8; 256];
  41. assert_eq!(rot.read(&mut buf).unwrap(), 256);
  42. for i in 0..=255 {
  43. if input[i] != buf[i] {
  44. assert!(input[i].is_ascii_alphabetic());
  45. assert!(buf[i].is_ascii_alphabetic());
  46. }
  47. }
  48. }
  49. }