forked from jfrog/jfrog-client-go
/
checksum.go
71 lines (62 loc) · 1.62 KB
/
checksum.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package checksum
import (
"bufio"
"crypto/md5"
"crypto/sha1"
"fmt"
"hash"
"io"
"os"
"github.com/cobalt77/jfrog-client-go/utils/errorutils"
"github.com/cobalt77/jfrog-client-go/utils/io/fileutils/checksum/utils"
)
type Algorithm int
const (
MD5 Algorithm = iota
SHA1
SHA256
)
var algorithmFunc = map[Algorithm](func() hash.Hash){
MD5: md5.New,
SHA1: sha1.New,
// TODO - Uncomment `Sha256` population when Artifactory support Sha256 checksum validation
//SHA256: sha256.New,
}
// Calc all hashes at once using AsyncMultiWriter therefore the file is read only once.
func Calc(reader io.Reader, checksumType ...Algorithm) (map[Algorithm]string, error) {
hashes := getChecksumByAlgorithm(checksumType...)
var multiWriter io.Writer
pageSize := os.Getpagesize()
sizedReader := bufio.NewReaderSize(reader, pageSize)
var hashWriter []io.Writer
for _, v := range hashes {
hashWriter = append(hashWriter, v)
}
multiWriter = utils.AsyncMultiWriter(hashWriter...)
_, err := io.Copy(multiWriter, sizedReader)
if errorutils.CheckError(err) != nil {
return nil, err
}
results := sumResults(hashes)
return results, nil
}
func sumResults(hashes map[Algorithm]hash.Hash) map[Algorithm]string {
results := map[Algorithm]string{}
for k, v := range hashes {
results[k] = fmt.Sprintf("%x", v.Sum(nil))
}
return results
}
func getChecksumByAlgorithm(checksumType ...Algorithm) map[Algorithm]hash.Hash {
hashes := map[Algorithm]hash.Hash{}
if len(checksumType) == 0 {
for k, v := range algorithmFunc {
hashes[k] = v()
}
return hashes
}
for _, v := range checksumType {
hashes[v] = algorithmFunc[v]()
}
return hashes
}