github.com/whamcloud/lemur@v0.0.0-20190827193804-4655df8a52af/pkg/checksum/checksum.go (about) 1 // Copyright (c) 2018 DDN. All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE file. 4 5 package checksum 6 7 import ( 8 "crypto/sha1" 9 "hash" 10 "io" 11 "os" 12 13 "github.com/pkg/errors" 14 ) 15 16 type ( 17 // Writer wraps an io.WriterAt and updates the checksum 18 // with every write. 19 Writer interface { 20 io.Writer 21 Sum() []byte 22 } 23 24 // Sha1HashWriter implements Writer and uses the SHA1 25 // algorithm to calculate the file checksum 26 Sha1HashWriter struct { 27 dest io.Writer 28 cksum hash.Hash 29 } 30 31 // NoopHashWriter implements Writer but doesn't 32 // actually calculate a checksum 33 NoopHashWriter struct { 34 dest io.Writer 35 } 36 ) 37 38 // NewSha1HashWriter returns a new Sha1HashWriter 39 func NewSha1HashWriter(dest io.Writer) Writer { 40 return &Sha1HashWriter{ 41 dest: dest, 42 cksum: sha1.New(), 43 } 44 } 45 46 // Write updates the checksum and writes the byte slice at offset 47 func (hw *Sha1HashWriter) Write(b []byte) (int, error) { 48 _, err := hw.cksum.Write(b) 49 if err != nil { 50 return 0, errors.Wrap(err, "updating checksum failed") 51 } 52 return hw.dest.Write(b) 53 } 54 55 // Sum returns the checksum 56 func (hw *Sha1HashWriter) Sum() []byte { 57 return hw.cksum.Sum(nil) 58 } 59 60 // NewNoopHashWriter returns a new NoopHashWriter 61 func NewNoopHashWriter(dest io.Writer) Writer { 62 return &NoopHashWriter{ 63 dest: dest, 64 } 65 } 66 67 // WriteAt writes the byte slice at offset 68 func (hw *NoopHashWriter) Write(b []byte) (int, error) { 69 return hw.dest.Write(b) 70 } 71 72 // Sum returns a dummy checksum 73 func (hw *NoopHashWriter) Sum() []byte { 74 return []byte{} 75 } 76 77 // FileSha1Sum returns the SHA1 checksum for the supplied file path 78 func FileSha1Sum(filePath string) ([]byte, error) { 79 file, err := os.Open(filePath) 80 if err != nil { 81 return nil, errors.Wrapf(err, "Failed to open %s for checksum", filePath) 82 } 83 defer file.Close() 84 85 hash := sha1.New() 86 _, err = io.Copy(hash, file) 87 if err != nil { 88 return nil, errors.Wrapf(err, "Failed to compute checksum for %s") 89 } 90 91 return hash.Sum(nil), nil 92 }