| package plumbing |
| |
| import ( |
| "bytes" |
| "crypto/sha1" |
| "encoding/hex" |
| "hash" |
| "sort" |
| "strconv" |
| ) |
| |
| // Hash SHA1 hased content |
| type Hash [20]byte |
| |
| // ZeroHash is Hash with value zero |
| var ZeroHash Hash |
| |
| // ComputeHash compute the hash for a given ObjectType and content |
| func ComputeHash(t ObjectType, content []byte) Hash { |
| h := NewHasher(t, int64(len(content))) |
| h.Write(content) |
| return h.Sum() |
| } |
| |
| // NewHash return a new Hash from a hexadecimal hash representation |
| func NewHash(s string) Hash { |
| b, _ := hex.DecodeString(s) |
| |
| var h Hash |
| copy(h[:], b) |
| |
| return h |
| } |
| |
| func (h Hash) IsZero() bool { |
| var empty Hash |
| return h == empty |
| } |
| |
| func (h Hash) String() string { |
| return hex.EncodeToString(h[:]) |
| } |
| |
| type Hasher struct { |
| hash.Hash |
| } |
| |
| func NewHasher(t ObjectType, size int64) Hasher { |
| h := Hasher{sha1.New()} |
| h.Write(t.Bytes()) |
| h.Write([]byte(" ")) |
| h.Write([]byte(strconv.FormatInt(size, 10))) |
| h.Write([]byte{0}) |
| return h |
| } |
| |
| func (h Hasher) Sum() (hash Hash) { |
| copy(hash[:], h.Hash.Sum(nil)) |
| return |
| } |
| |
| // HashesSort sorts a slice of Hashes in increasing order. |
| func HashesSort(a []Hash) { |
| sort.Sort(HashSlice(a)) |
| } |
| |
| // HashSlice attaches the methods of sort.Interface to []Hash, sorting in |
| // increasing order. |
| type HashSlice []Hash |
| |
| func (p HashSlice) Len() int { return len(p) } |
| func (p HashSlice) Less(i, j int) bool { return bytes.Compare(p[i][:], p[j][:]) < 0 } |
| func (p HashSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } |