use std::io::{Read, BufReader, Result};
struct Rot13<R: Read> {
r: R,
}
impl<R: Read> Rot13<R> {
fn new(r: R) -> Rot13<R> {
Rot13{
r: r,
}
}
}
impl<R: Read> Read for Rot13<R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let r = match self.r.read(buf) {
Ok(r) => r,
Err(err) => {
return Err(err);
}
};
for i in 0..buf.len() {
let c = buf[i] as char;
if (c >= 'A') && (c <= 'Z') {
buf[i] = rotate(buf[i], 'Z' as u8);
}
else if (c >= 'a') && (c <= 'z') {
buf[i] = rotate(buf[i], 'z' as u8);
}
}
Ok(r)
}
}
fn rotate(mut c: u8, max: u8) -> u8 {
c += 13;
if c > max {
c -= 26;
}
c
}
fn main() {
let mut r = Rot13::new(BufReader::new("Pna V unir fbzr pnxr, cyrnfr?".as_bytes()));
let mut s = String::new();
r.read_to_string(&mut s).unwrap();
println!("{}", s);
}
dXNlIHN0ZDo6aW86OntSZWFkLCBCdWZSZWFkZXIsIFJlc3VsdH07CgpzdHJ1Y3QgUm90MTM8UjogUmVhZD4gewogICAgcjogUiwKfQoKaW1wbDxSOiBSZWFkPiBSb3QxMzxSPiB7CiAgICBmbiBuZXcocjogUikgLT4gUm90MTM8Uj4gewogICAgICAgIFJvdDEzewogICAgICAgICAgICByOiByLAogICAgICAgIH0KICAgIH0KfQoKaW1wbDxSOiBSZWFkPiBSZWFkIGZvciBSb3QxMzxSPiB7CiAgICBmbiByZWFkKCZtdXQgc2VsZiwgYnVmOiAmbXV0IFt1OF0pIC0+IFJlc3VsdDx1c2l6ZT4gewogICAgICAgIGxldCByID0gbWF0Y2ggc2VsZi5yLnJlYWQoYnVmKSB7CiAgICAgICAgICAgIE9rKHIpID0+IHIsCiAgICAgICAgICAgIEVycihlcnIpID0+IHsKICAgICAgICAgICAgICAgIHJldHVybiBFcnIoZXJyKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgZm9yIGkgaW4gMC4uYnVmLmxlbigpIHsKICAgICAgICAgICAgbGV0IGMgPSBidWZbaV0gYXMgY2hhcjsKICAgICAgICAgICAgaWYgKGMgPj0gJ0EnKSAmJiAoYyA8PSAnWicpIHsKICAgICAgICAgICAgICAgIGJ1ZltpXSA9IHJvdGF0ZShidWZbaV0sICdaJyBhcyB1OCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoYyA+PSAnYScpICYmIChjIDw9ICd6JykgewogICAgICAgICAgICAgICAgYnVmW2ldID0gcm90YXRlKGJ1ZltpXSwgJ3onIGFzIHU4KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBPayhyKQogICAgfQp9CgpmbiByb3RhdGUobXV0IGM6IHU4LCBtYXg6IHU4KSAtPiB1OCB7CiAgICBjICs9IDEzOwogICAgaWYgYyA+IG1heCB7CiAgICAgICAgYyAtPSAyNjsKICAgIH0KICAgIAogICAgYwp9CgpmbiBtYWluKCkgewogICAgbGV0IG11dCByID0gUm90MTM6Om5ldyhCdWZSZWFkZXI6Om5ldygiUG5hIFYgdW5pciBmYnpyIHBueHIsIGN5cm5mcj8iLmFzX2J5dGVzKCkpKTsKICAgIAogICAgbGV0IG11dCBzID0gU3RyaW5nOjpuZXcoKTsKICAgIHIucmVhZF90b19zdHJpbmcoJm11dCBzKS51bndyYXAoKTsKICAgIHByaW50bG4hKCJ7fSIsIHMpOwp9