堆叠写入器和zlib写入器的校验和错误。

huangapple go评论163阅读模式
英文:

Wrong checksum on stacked writer & zlib.writer

问题

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

我的单元测试用例对于第一个写入器的一些测试数据通过了,但对于第二个写入器失败了。

我在哪里做错了?

英文:

I have two object writers, first one encapsulates io.Writer and along writes it also coputes SHA1 checksum of content, and second encapsulates first and writes zlib compressed data.

My unit test case with some test data passes for first writer, but fails with second.

Where and what I'm doing wrong?

code snippet:

  1. import (
  2. "compress/zlib"
  3. "crypto/sha1"
  4. "hash"
  5. "io"
  6. )
  7. type ObjectWriter interface {
  8. io.Writer
  9. Commit() ([]byte, error)
  10. }
  11. type oWriter struct {
  12. writer io.Writer
  13. sum hash.Hash
  14. }
  15. func (ow *oWriter) Write(b []byte) (int, error) {
  16. ow.sum.Write(b) // Hash writer never returs error -> hash.Hash docs
  17. return ow.writer.Write(b)
  18. }
  19. func (ow *oWriter) Commit() ([]byte, error) {
  20. return ow.sum.Sum(nil), nil
  21. }
  22. func NewWriter(w io.Writer) ObjectWriter {
  23. return &oWriter{w, sha1.New()}
  24. }
  25. type compressedWriter struct {
  26. oWriter ObjectWriter
  27. zWriter io.WriteCloser
  28. }
  29. func (ow *compressedWriter) Write(b []byte) (int, error) {
  30. return ow.zWriter.Write(b)
  31. }
  32. func (ow *compressedWriter) Commit() ([]byte, error) {
  33. if err := ow.zWriter.Close(); err != nil {
  34. return nil, err
  35. }
  36. return ow.oWriter.Commit()
  37. }
  38. func NewCompressedWriter(w io.Writer) ObjectWriter {
  39. ow := NewWriter(w)
  40. zw := zlib.NewWriter(ow)
  41. return &compressedWriter{ow, zw}
  42. }

passing test case:

  1. func TestObjectWriter(t *testing.T) {
  2. var buf bytes.Buffer
  3. ow := NewWriter(&buf)
  4. ow.Write([]byte("test content"))
  5. sum, err := ow.Commit()
  6. if err != nil {
  7. t.Errorf("Commit error: %s", err)
  8. }
  9. expected := "1eebdf4fdc9fc7bf283031b93f9aef3338de9052"
  10. given := fmt.Sprintf("%x", sum)
  11. if expected != given {
  12. t.Errorf("Invalid SHA1 sum: <%s> != <%s>", expected, given)
  13. }
  14. }

failing test case:

  1. func TestCompressedObjectWriter(t *testing.T) {
  2. var buf bytes.Buffer
  3. ow := NewCompressedWriter(&buf)
  4. ow.Write([]byte("test content"))
  5. sum, err := ow.Commit()
  6. if err != nil {
  7. t.Errorf("Commit error: %s", err)
  8. }
  9. expected := "7efbe4015afd95478282c3774f47b4195031d27e"
  10. given := fmt.Sprintf("%x", sum)
  11. if expected != given {
  12. t.Errorf("Invalid SHA1 sum: <%s> != <%s>", expected, given)
  13. }
  14. }

答案1

得分: 0

你的测试输出是什么?

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

例如,

  1. package main
  2. import (
  3. "bytes"
  4. "compress/zlib"
  5. "crypto/sha1"
  6. "fmt"
  7. )
  8. func ObjectHash(s string) (string, error) {
  9. var buf bytes.Buffer
  10. _, err := buf.Write([]byte(s))
  11. if err != nil {
  12. return "", err
  13. }
  14. hash := sha1.New()
  15. hash.Write(buf.Bytes())
  16. sum := fmt.Sprintf("%x", hash.Sum(nil))
  17. return sum, nil
  18. }
  19. func CompressedHash(s string) (string, error) {
  20. var buf bytes.Buffer
  21. zw := zlib.NewWriter(&buf)
  22. _, err := zw.Write([]byte(s))
  23. if err != nil {
  24. return "", err
  25. }
  26. zw.Close()
  27. hash := sha1.New()
  28. hash.Write(buf.Bytes())
  29. sum := fmt.Sprintf("%x", hash.Sum(nil))
  30. return sum, nil
  31. }
  32. func main() {
  33. s := "test content"
  34. sum, err := ObjectHash(s)
  35. if err == nil {
  36. fmt.Println("Object: ", sum)
  37. }
  38. sum, err = CompressedHash(s)
  39. if err == nil {
  40. fmt.Println("Compressed:", sum)
  41. }
  42. }

输出:

  1. Object: 1eebdf4fdc9fc7bf283031b93f9aef3338de9052
  2. Compressed: 8138de8ff9d0cd30126f7e26191996dce781d652

如果你比较苹果和橙子,SHA1算法可以区分不同类型的水果。

苹果(Go):

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

橙子(Python):

  1. 00000000 78 9c 2b 49 2d 2e 51 48 ce cf 2b 49 cd 2b 01 00 |x.+I-.QH..+I.+..|
  2. 00000010 1f 29 04 dc |.)..|
  3. $ sha1sum oranges
  4. 7efbe4015afd95478282c3774f47b4195031d27e oranges
英文:

What was your test output?

How did you calculate your expected values?

For example,

  1. package main
  2. import (
  3. "bytes"
  4. "compress/zlib"
  5. "crypto/sha1"
  6. "fmt"
  7. )
  8. func ObjectHash(s string) (string, error) {
  9. var buf bytes.Buffer
  10. _, err := buf.Write([]byte(s))
  11. if err != nil {
  12. return "", err
  13. }
  14. hash := sha1.New()
  15. hash.Write(buf.Bytes())
  16. sum := fmt.Sprintf("%x", hash.Sum(nil))
  17. return sum, nil
  18. }
  19. func CompressedHash(s string) (string, error) {
  20. var buf bytes.Buffer
  21. zw := zlib.NewWriter(&buf)
  22. _, err := zw.Write([]byte(s))
  23. if err != nil {
  24. return "", err
  25. }
  26. zw.Close()
  27. hash := sha1.New()
  28. hash.Write(buf.Bytes())
  29. sum := fmt.Sprintf("%x", hash.Sum(nil))
  30. return sum, nil
  31. }
  32. func main() {
  33. s := "test content"
  34. sum, err := ObjectHash(s)
  35. if err == nil {
  36. fmt.Println("Object: ", sum)
  37. }
  38. sum, err = CompressedHash(s)
  39. if err == nil {
  40. fmt.Println("Compressed:", sum)
  41. }
  42. }

Output:

  1. Object: 1eebdf4fdc9fc7bf283031b93f9aef3338de9052
  2. Compressed: 8138de8ff9d0cd30126f7e26191996dce781d652

If you compare apples and oranges, SHA1, by design, can tell the difference between different types of fruit.

  1. Apples (Go):
  2. 00000000 78 9c 2a 49 2d 2e 51 48 ce cf 2b 49 cd 2b 01 04 |x.*I-.QH..+I.+..|
  3. 00000010 00 00 ff ff 1f 29 04 dc |.....)..|
  4. $ sha1sum apples
  5. 8138de8ff9d0cd30126f7e26191996dce781d652 apples
  6. Oranges (Python):
  7. 00000000 78 9c 2b 49 2d 2e 51 48 ce cf 2b 49 cd 2b 01 00 |x.+I-.QH..+I.+..|
  8. 00000010 1f 29 04 dc |.)..|
  9. $ sha1sum oranges
  10. 7efbe4015afd95478282c3774f47b4195031d27e oranges

huangapple
  • 本文由 发表于 2013年5月23日 05:06:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/16701567.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定