堆叠的写入器上的错误校验和& zlib.writer

时间:2013-05-22 21:06:21

标签: go sha1 zlib

我有两个对象编写器,第一个封装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)
    }
}

1 个答案:

答案 0 :(得分: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