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 }