git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/checksum/checksum.go (about)

     1  package checksum
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"encoding/hex"
     6  	"errors"
     7  	"fmt"
     8  
     9  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
    10  	"git.frostfs.info/TrueCloudLab/tzhash/tz"
    11  )
    12  
    13  // Checksum represents checksum of some digital data.
    14  //
    15  // Checksum is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs.Checksum
    16  // message. See ReadFromV2 / WriteToV2 methods.
    17  //
    18  // Instances can be created using built-in var declaration.
    19  //
    20  // Note that direct typecast is not safe and may result in loss of compatibility:
    21  //
    22  //	_ = Checksum(refs.Checksum{}) // not recommended
    23  type Checksum refs.Checksum
    24  
    25  // Type represents the enumeration
    26  // of checksum types.
    27  type Type refs.ChecksumType
    28  
    29  const (
    30  	// Unknown is an undefined checksum type.
    31  	Unknown Type = Type(refs.UnknownChecksum)
    32  
    33  	// SHA256 is a SHA256 checksum type.
    34  	SHA256 = Type(refs.SHA256)
    35  
    36  	// TZ is a Tillich-Zémor checksum type.
    37  	TZ = Type(refs.TillichZemor)
    38  )
    39  
    40  // ReadFromV2 reads Checksum from the refs.Checksum message. Checks if the
    41  // message conforms to FrostFS API V2 protocol.
    42  //
    43  // See also WriteToV2.
    44  func (c *Checksum) ReadFromV2(m refs.Checksum) error {
    45  	if len(m.GetSum()) == 0 {
    46  		return errors.New("missing value")
    47  	}
    48  
    49  	switch m.GetType() {
    50  	default:
    51  		return fmt.Errorf("unsupported type %v", m.GetType())
    52  	case refs.SHA256, refs.TillichZemor:
    53  	}
    54  
    55  	*c = Checksum(m)
    56  
    57  	return nil
    58  }
    59  
    60  // WriteToV2 writes Checksum to the refs.Checksum message.
    61  // The message must not be nil.
    62  //
    63  // See also ReadFromV2.
    64  func (c Checksum) WriteToV2(m *refs.Checksum) {
    65  	*m = (refs.Checksum)(c)
    66  }
    67  
    68  // Type returns checksum type.
    69  //
    70  // Zero Checksum has Unknown checksum type.
    71  //
    72  // See also SetTillichZemor and SetSHA256.
    73  func (c Checksum) Type() Type {
    74  	v2 := (refs.Checksum)(c)
    75  	switch v2.GetType() {
    76  	case refs.SHA256:
    77  		return SHA256
    78  	case refs.TillichZemor:
    79  		return TZ
    80  	default:
    81  		return Unknown
    82  	}
    83  }
    84  
    85  // Value returns checksum bytes. Return value
    86  // MUST NOT be mutated.
    87  //
    88  // Zero Checksum has nil sum.
    89  //
    90  // See also SetTillichZemor and SetSHA256.
    91  func (c Checksum) Value() []byte {
    92  	v2 := (refs.Checksum)(c)
    93  	return v2.GetSum()
    94  }
    95  
    96  // SetSHA256 sets checksum to SHA256 hash.
    97  //
    98  // See also Calculate.
    99  func (c *Checksum) SetSHA256(v [sha256.Size]byte) {
   100  	v2 := (*refs.Checksum)(c)
   101  
   102  	v2.SetType(refs.SHA256)
   103  	v2.SetSum(v[:])
   104  }
   105  
   106  // Calculate calculates checksum and sets it
   107  // to the passed checksum. Checksum must not be nil.
   108  //
   109  // Does nothing if the passed type is not one of the:
   110  //   - SHA256;
   111  //   - TZ.
   112  //
   113  // Does not mutate the passed value.
   114  //
   115  // See also SetSHA256, SetTillichZemor.
   116  func Calculate(c *Checksum, t Type, v []byte) {
   117  	switch t {
   118  	case SHA256:
   119  		c.SetSHA256(sha256.Sum256(v))
   120  	case TZ:
   121  		c.SetTillichZemor(tz.Sum(v))
   122  	default:
   123  	}
   124  }
   125  
   126  // SetTillichZemor sets checksum to Tillich-Zémor hash.
   127  //
   128  // See also Calculate.
   129  func (c *Checksum) SetTillichZemor(v [tz.Size]byte) {
   130  	v2 := (*refs.Checksum)(c)
   131  
   132  	v2.SetType(refs.TillichZemor)
   133  	v2.SetSum(v[:])
   134  }
   135  
   136  // String implements fmt.Stringer.
   137  //
   138  // String is designed to be human-readable, and its format MAY differ between
   139  // SDK versions.
   140  func (c Checksum) String() string {
   141  	v2 := (refs.Checksum)(c)
   142  	return fmt.Sprintf("%s:%s", c.Type(), hex.EncodeToString(v2.GetSum()))
   143  }
   144  
   145  // String implements fmt.Stringer.
   146  //
   147  // String is designed to be human-readable, and its format MAY differ between
   148  // SDK versions.
   149  func (m Type) String() string {
   150  	var m2 refs.ChecksumType
   151  
   152  	switch m {
   153  	default:
   154  		m2 = refs.UnknownChecksum
   155  	case TZ:
   156  		m2 = refs.TillichZemor
   157  	case SHA256:
   158  		m2 = refs.SHA256
   159  	}
   160  
   161  	return m2.String()
   162  }