mirror of
https://github.com/versity/versitygw.git
synced 2026-01-05 11:24:52 +00:00
96 lines
2.2 KiB
Go
96 lines
2.2 KiB
Go
package command
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"hash"
|
|
"hash/crc32"
|
|
"reflect"
|
|
|
|
"github.com/minio/crc64nvme"
|
|
)
|
|
|
|
type Payload struct {
|
|
dataSource DataSource
|
|
payloadType PayloadType
|
|
checksumType string
|
|
dataSizeCalculated bool
|
|
dataSize int64
|
|
}
|
|
|
|
func GetBase64ChecksumLength(checksumType string) (int64, error) {
|
|
switch checksumType {
|
|
case ChecksumCRC32, ChecksumCRC32C:
|
|
return 8, nil
|
|
case ChecksumSHA256:
|
|
return 44, nil
|
|
case ChecksumSHA1:
|
|
return 28, nil
|
|
case ChecksumCRC64NVME:
|
|
return 12, nil
|
|
}
|
|
return 0, errors.New("unrecognized checksum type: " + checksumType)
|
|
}
|
|
|
|
func (p *Payload) GetDataSize() (int64, error) {
|
|
if !p.dataSizeCalculated {
|
|
if p.dataSource != nil {
|
|
dataSize, err := p.dataSource.SourceDataByteSize()
|
|
if err != nil {
|
|
return 0, fmt.Errorf("error getting payload data size: %w", err)
|
|
}
|
|
p.dataSize = dataSize
|
|
} else {
|
|
p.dataSize = 0
|
|
}
|
|
p.dataSizeCalculated = true
|
|
}
|
|
return p.dataSize, nil
|
|
}
|
|
|
|
func (p *Payload) getChecksumHasher() hash.Hash {
|
|
switch p.checksumType {
|
|
case ChecksumSHA256:
|
|
return sha256.New()
|
|
case ChecksumSHA1:
|
|
return sha1.New()
|
|
case ChecksumCRC32:
|
|
return crc32.NewIEEE()
|
|
case ChecksumCRC32C:
|
|
return crc32.New(crc32.MakeTable(crc32.Castagnoli))
|
|
case ChecksumCRC64NVME:
|
|
return crc64nvme.New()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *Payload) getBase64Checksum(hasher hash.Hash) (string, error) {
|
|
switch p.checksumType {
|
|
case ChecksumSHA256, ChecksumSHA1, ChecksumCRC32:
|
|
return base64.StdEncoding.EncodeToString(hasher.Sum(nil)), nil
|
|
case ChecksumCRC32C:
|
|
var b [4]byte
|
|
hasher32, ok := hasher.(hash.Hash32)
|
|
if !ok {
|
|
return "", fmt.Errorf("'%v' not a Hash32 interface", reflect.TypeOf(hasher).String())
|
|
}
|
|
sum := hasher32.Sum32()
|
|
binary.BigEndian.PutUint32(b[:], sum)
|
|
return base64.StdEncoding.EncodeToString(b[:]), nil
|
|
case ChecksumCRC64NVME:
|
|
var b [8]byte
|
|
hasher64, ok := hasher.(hash.Hash64)
|
|
if !ok {
|
|
return "", fmt.Errorf("'%v' not a Hash64 interface", reflect.TypeOf(hasher).String())
|
|
}
|
|
sum := hasher64.Sum64()
|
|
binary.BigEndian.PutUint64(b[:], sum)
|
|
return base64.StdEncoding.EncodeToString(b[:]), nil
|
|
}
|
|
return "", fmt.Errorf("invalid checksum type specified: '%s'", p.checksumType)
|
|
}
|