1

我有两个对象编写器,第一个封装io.Writer并沿写入它还计算内容的 SHA1 校验和,第二个首先封装并写入 zlib 压缩数据。

我的带有一些测试数据的单元测试用例通过了第一位作者,但第二位作者失败了。

我在哪里做错了什么?

代码片段:

import (
    "compress/zlib"
    "crypto/sha1"
    "hash"
    "io"
)

type ObjectWriter interface {
    io.Writer
    Commit() ([]byte, error)
}

type oWriter struct {
    writer io.Writer
    sum    hash.Hash
}

func (ow *oWriter) Write(b []byte) (int, error) {
    ow.sum.Write(b)  // Hash writer never returs error -> hash.Hash docs
    return ow.writer.Write(b)
}

func (ow *oWriter) Commit() ([]byte, error) {
    return ow.sum.Sum(nil), nil
}

func NewWriter(w io.Writer) ObjectWriter {
    return &oWriter{w, sha1.New()}
}

type compressedWriter struct {
    oWriter ObjectWriter
    zWriter io.WriteCloser
}

func (ow *compressedWriter) Write(b []byte) (int, error) {
    return ow.zWriter.Write(b)
}

func (ow *compressedWriter) Commit() ([]byte, error) {
    if err := ow.zWriter.Close(); err != nil {
        return nil, err
    }

    return ow.oWriter.Commit()
}

func NewCompressedWriter(w io.Writer) ObjectWriter {
    ow := NewWriter(w)
    zw := zlib.NewWriter(ow)

    return &compressedWriter{ow, zw}
}

通过测试用例:

func TestObjectWriter(t *testing.T) {
    var buf bytes.Buffer

    ow := NewWriter(&buf)
    ow.Write([]byte("test content"))
    sum, err := ow.Commit()

    if err != nil {
        t.Errorf("Commit error: %s", err)
    }

    expected := "1eebdf4fdc9fc7bf283031b93f9aef3338de9052"
    given := fmt.Sprintf("%x", sum)

    if  expected != given {
        t.Errorf("Invalid SHA1 sum: <%s> != <%s>", expected, given)
    }
}

失败的测试用例:

func TestCompressedObjectWriter(t *testing.T) {
    var buf bytes.Buffer

    ow := NewCompressedWriter(&buf)
    ow.Write([]byte("test content"))
    sum, err := ow.Commit()

    if err != nil {
        t.Errorf("Commit error: %s", err)
    }

    expected := "7efbe4015afd95478282c3774f47b4195031d27e"
    given := fmt.Sprintf("%x", sum)

    if  expected != given {
        t.Errorf("Invalid SHA1 sum: <%s> != <%s>", expected, given)
    }
}
4

1 回答 1

0

你的测试输出是什么?

你是如何计算你的期望值的?

例如,

package main

import (
    "bytes"
    "compress/zlib"
    "crypto/sha1"
    "fmt"
)

func ObjectHash(s string) (string, error) {
    var buf bytes.Buffer
    _, err := buf.Write([]byte(s))
    if err != nil {
        return "", err
    }
    hash := sha1.New()
    hash.Write(buf.Bytes())
    sum := fmt.Sprintf("%x", hash.Sum(nil))
    return sum, nil
}

func CompressedHash(s string) (string, error) {
    var buf bytes.Buffer
    zw := zlib.NewWriter(&buf)
    _, err := zw.Write([]byte(s))
    if err != nil {
        return "", err
    }
    zw.Close()
    hash := sha1.New()
    hash.Write(buf.Bytes())
    sum := fmt.Sprintf("%x", hash.Sum(nil))
    return sum, nil
}

func main() {
    s := "test content"
    sum, err := ObjectHash(s)
    if err == nil {
        fmt.Println("Object:    ", sum)
    }
    sum, err = CompressedHash(s)
    if err == nil {
        fmt.Println("Compressed:", sum)
    }
}

输出:

Object:     1eebdf4fdc9fc7bf283031b93f9aef3338de9052
Compressed: 8138de8ff9d0cd30126f7e26191996dce781d652

如果您比较苹果和橙子,SHA1 设计上可以区分不同类型的水果。

Apples (Go):

00000000  78 9c 2a 49 2d 2e 51 48  ce cf 2b 49 cd 2b 01 04  |x.*I-.QH..+I.+..|
00000010  00 00 ff ff 1f 29 04 dc                           |.....)..|

$ sha1sum apples
8138de8ff9d0cd30126f7e26191996dce781d652  apples

Oranges (Python):

00000000  78 9c 2b 49 2d 2e 51 48  ce cf 2b 49 cd 2b 01 00  |x.+I-.QH..+I.+..|
00000010  1f 29 04 dc                                       |.)..|

$ sha1sum oranges
7efbe4015afd95478282c3774f47b4195031d27e  oranges
于 2013-05-22T22:07:46.390 回答