aboutsummaryrefslogtreecommitdiff
path: root/hash.go
diff options
context:
space:
mode:
Diffstat (limited to 'hash.go')
-rw-r--r--hash.go112
1 files changed, 70 insertions, 42 deletions
diff --git a/hash.go b/hash.go
index df39ac30..cbaac821 100644
--- a/hash.go
+++ b/hash.go
@@ -6,59 +6,74 @@ import (
"encoding/hex"
)
-// maxHashSize MUST be equal to (or larger than) the size of the
-// largest hash supported in hashFuncs.
+// maxHashSize MUST be >= the largest supported algorithm size.
const maxHashSize = sha256.Size
// hashAlgorithm identifies the hash algorithm used for Git object IDs.
type hashAlgorithm uint8
-// hashFuncs maps hash algorithm to hash function.
-var hashFuncs = map[hashAlgorithm]hashFunc{
- hashAlgoSHA1: func(data []byte) Hash {
- sum := sha1.Sum(data)
- var h Hash
- copy(h.data[:], sum[:])
- h.algo = hashAlgoSHA1
- return h
- },
- hashAlgoSHA256: func(data []byte) Hash {
- sum := sha256.Sum256(data)
- var h Hash
- copy(h.data[:], sum[:])
- h.algo = hashAlgoSHA256
- return h
- },
-}
-
const (
hashAlgoUnknown hashAlgorithm = iota
hashAlgoSHA1
hashAlgoSHA256
)
-// size returns the hash size in bytes.
-func (algo hashAlgorithm) size() int {
- switch algo {
- case hashAlgoSHA1:
- return sha1.Size
- case hashAlgoSHA256:
- return sha256.Size
- default:
- return 0
- }
+type hashAlgorithmDetails struct {
+ name string
+ size int
+ sum func([]byte) Hash
+}
+
+var hashAlgorithmTable = [...]hashAlgorithmDetails{
+ hashAlgoUnknown: {},
+ hashAlgoSHA1: {
+ name: "sha1",
+ size: sha1.Size,
+ sum: func(data []byte) Hash {
+ sum := sha1.Sum(data)
+ var h Hash
+ copy(h.data[:], sum[:])
+ h.algo = hashAlgoSHA1
+ return h
+ },
+ },
+ hashAlgoSHA256: {
+ name: "sha256",
+ size: sha256.Size,
+ sum: func(data []byte) Hash {
+ sum := sha256.Sum256(data)
+ var h Hash
+ copy(h.data[:], sum[:])
+ h.algo = hashAlgoSHA256
+ return h
+ },
+ },
+}
+
+func (algo hashAlgorithm) info() hashAlgorithmDetails {
+ return hashAlgorithmTable[algo]
+}
+
+// Size returns the hash size in bytes.
+func (algo hashAlgorithm) Size() int {
+ return algo.info().size
}
// String returns the canonical name of the hash algorithm.
func (algo hashAlgorithm) String() string {
- switch algo {
- case hashAlgoSHA1:
- return "sha1"
- case hashAlgoSHA256:
- return "sha256"
- default:
+ inf := algo.info()
+ if inf.name == "" {
return "unknown"
}
+ return inf.name
+}
+
+func (algo hashAlgorithm) HexLen() int {
+ return algo.Size() * 2
+}
+
+func (algo hashAlgorithm) Sum(data []byte) Hash {
+ return algo.info().sum(data)
}
// Hash represents a Git object ID.
@@ -67,12 +82,9 @@ type Hash struct {
data [maxHashSize]byte
}
-// hashFunc is a function that computes a hash from input data.
-type hashFunc func([]byte) Hash
-
// String returns a hexadecimal string representation of the hash.
func (hash Hash) String() string {
- size := hash.algo.size()
+ size := hash.algo.Size()
if size == 0 {
return ""
}
@@ -81,7 +93,7 @@ func (hash Hash) String() string {
// Bytes returns a copy of the hash's bytes.
func (hash Hash) Bytes() []byte {
- size := hash.algo.size()
+ size := hash.algo.Size()
if size == 0 {
return nil
}
@@ -90,5 +102,21 @@ func (hash Hash) Bytes() []byte {
// Size returns the hash size.
func (hash Hash) Size() int {
- return hash.algo.size()
+ return hash.algo.Size()
+}
+
+var algoByName = map[string]hashAlgorithm{}
+
+func init() {
+ for algo, info := range hashAlgorithmTable {
+ if info.name == "" {
+ continue
+ }
+ algoByName[info.name] = hashAlgorithm(algo)
+ }
+}
+
+func parseHashAlgorithm(s string) (hashAlgorithm, bool) {
+ algo, ok := algoByName[s]
+ return algo, ok
}