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  }