Exercise: rot13Reader
A common pattern is an io.Reader that wraps another io.Reader
, modifying the stream in some way.
For example, the gzip.NewReader function takes an io.Reader
(a stream of compressed data) and returns a *gzip.Reader
that also implements io.Reader
(a stream of the decompressed data).
Implement a rot13Reader
that implements io.Reader
and reads from anio.Reader
, modifying the stream by applying the rot13 substitution cipher to all alphabetical characters.
The rot13Reader
type is provided for you. Make it an io.Reader
by implementing its Read
method.
package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func (rot13 rot13Reader) Read(b []byte) (int, error) {
n, err := rot13.r.Read(b)
if err != io.EOF {
for i := 0; i < n; i++ {
ch := b[i]
if (ch >= 65 && ch <= 77) || (ch >= 97 && ch <= 109) {
b[i] = ch + 13
} else if (ch >= 78 && ch <= 90) || (ch >= 110 && ch <= 122) {
b[i] = ch - 13
}
}
}
return n, err
}
func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}