// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package s3checksum import ( "encoding/base64" "encoding/csv" "encoding/hex" "encoding/json" "fmt" "os" ) var ( printHex = false ) // PrintHexMode sets the CLI to print checksums in hex instead of base64 func PrintHexMode() { printHex = true } type PartInfo struct { PartNumber int32 `json:"part_number"` Size int64 `json:"size"` Algorithm string `json:"algorithm"` Checksum ByteSlice `json:"checksum"` MD5Checksum []byte `json:""` } type ManifestFile struct { Filename string `json:"filename"` PartSize int `json:"part_size"` PartList []*PartInfo `json:"part_list"` Checksum ByteSlice `json:"checksum"` Etag []byte `json:"Etag"` Algorithm string `json:"algorithm"` } type ObjectAttributes struct { Filename string `json:"filename"` PartSize int `json:"part_size"` Algorithm string `json:"algorithm"` Checksum ByteSlice `json:"checksum"` Etag []byte `json:"Etag"` } type ByteSlice []byte func (m ByteSlice) MarshalJSON() ([]byte, error) { return json.Marshal(hex.EncodeToString(m)) } func (m *ByteSlice) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } n, err := hex.DecodeString(s) if err != nil { return err } *m = n return nil } func (m ByteSlice) String() string { if printHex { return hex.EncodeToString(m) } else { return base64.StdEncoding.EncodeToString(m) } } // WriteSimpleManifest is a simplified CSV that doesn't include part checksums, // only checksum of checksums. func WriteSimpleManifest(path string, mf []*ManifestFile) error { f, err := os.Create(path) if err != nil { return err } defer f.Close() rows := [][]string{} for _, v := range mf { partSize := fmt.Sprintf("%d", v.PartSize) checksumOfChecksums := fmt.Sprintf("%s-%d", v.Checksum.String(), len(v.PartList)) etag := fmt.Sprintf("%x-%d", v.Etag, len(v.PartList)) rows = append(rows, []string{ v.Filename, partSize, v.Algorithm, checksumOfChecksums, etag, }) } return csv.NewWriter(f).WriteAll(rows) }