练习 rot13Reader

问题

有种常见的模式是一个 io.Reader 包装另一个 io.Reader,然后通过某种方式修改其数据流。

例如,gzip.NewReader 函数接受一个 io.Reader(已压缩的数据流)并返回一个同样实现了 io.Reader 的 *gzip.Reader(解压后的数据流)。

编写一个实现了 io.Reader 并从另一个 io.Reader 中读取数据的 rot13Reader,通过应用 rot13 代换密码对数据流进行修改。

rot13Reader 类型已经提供。实现 Read 方法以满足 io.Reader。

背景知识

  1. 首先你需要了解io.Reader接口详细实现。
type Reader interface {
    Read(p []byte) (n int, err error)
}
//这里定义Reader接口,需要实现一个Read函数、方法,参数为数组 返回为字节数和错误值。
type error interface {
    Error() string
}
//错误的接口实现
  1. gzip.NewReader的实现可以帮助你快速实现下面的练习。
type Reader struct {
    Header       // valid after NewReader or Reader.Reset
    r            flate.Reader
    decompressor io.ReadCloser
    digest       uint32 // CRC-32, IEEE polynomial (section 8)
    size         uint32 // Uncompressed size (section 2.3.1)
    buf          [512]byte
    err          error
    multistream  bool
}
func NewReader(r io.Reader) (*Reader, error) {
    z := new(Reader)
    if err := z.Reset(r); err != nil {
        return nil, err
    }
    return z, nil
}
//gzip的NewReader实现
  1. 你需要了解rot13算法的实现。
//直接从golang源代码里面copy就好了。路径为go/src/bytes/bytes_test.go 974行
func rot13(r rune) rune {
    const step = 13
    if r >= 'a' && r <= 'z' {
        return ((r - 'a' + step) % 26) + 'a'
    }
    if r >= 'A' && r <= 'Z' {
        return ((r - 'A' + step) % 26) + 'A'
    }
    return r
}
//这里找到算法,并不能实现,需要参数为[]byte的实现方案。
func rot13(b byte) byte {
    var a byte
    switch {
    case b >= 'a' && b <= 'z':
        a = 'a'
    case b >= 'A' && b <= 'Z':
        a = 'A'
    default:
        return b
    }
    return (b-a+13)%26 + a
}

  1. 获取变量的类型
Using string formatting
func typeof(v interface{}) string {
    return fmt.Sprintf("%T", v)
}
Using reflect package

func typeof(v interface{}) string {
    return reflect.TypeOf(v).String()
}
Using type assertions

func typeof(v interface{}) string {
    switch v.(type) {
    case int:
        return "int"
    case float64:
        return "float64"
    //... etc
    default:
        return "unknown"
    }
}

实现思路

  1. 定义错误类,溢出
  2. 实现Read接口
  3. 实现rot13算法
  4. 逻辑实现先判断异常情况,返回对应的错误信息
  5. 正常就返回读取的字节数和nil
  6. 这里需要注意的r.r.Read这个调用,第一个r是类型rot13Reader,它的结构体有一个成员r,类型为io.Reader,这个接口只有一个方法Read.

实现代码

GitHub

参考链接

  1. 练习:rot13Reader
  2. rot13 加密
  3. How to find a type of an object in Go?
打赏作者

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注