You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hash.go 1.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package plumbing
  2. import (
  3. "bytes"
  4. "crypto/sha1"
  5. "encoding/hex"
  6. "hash"
  7. "sort"
  8. "strconv"
  9. )
  10. // Hash SHA1 hashed content
  11. type Hash [20]byte
  12. // ZeroHash is Hash with value zero
  13. var ZeroHash Hash
  14. // ComputeHash compute the hash for a given ObjectType and content
  15. func ComputeHash(t ObjectType, content []byte) Hash {
  16. h := NewHasher(t, int64(len(content)))
  17. h.Write(content)
  18. return h.Sum()
  19. }
  20. // NewHash return a new Hash from a hexadecimal hash representation
  21. func NewHash(s string) Hash {
  22. b, _ := hex.DecodeString(s)
  23. var h Hash
  24. copy(h[:], b)
  25. return h
  26. }
  27. func (h Hash) IsZero() bool {
  28. var empty Hash
  29. return h == empty
  30. }
  31. func (h Hash) String() string {
  32. return hex.EncodeToString(h[:])
  33. }
  34. type Hasher struct {
  35. hash.Hash
  36. }
  37. func NewHasher(t ObjectType, size int64) Hasher {
  38. h := Hasher{sha1.New()}
  39. h.Write(t.Bytes())
  40. h.Write([]byte(" "))
  41. h.Write([]byte(strconv.FormatInt(size, 10)))
  42. h.Write([]byte{0})
  43. return h
  44. }
  45. func (h Hasher) Sum() (hash Hash) {
  46. copy(hash[:], h.Hash.Sum(nil))
  47. return
  48. }
  49. // HashesSort sorts a slice of Hashes in increasing order.
  50. func HashesSort(a []Hash) {
  51. sort.Sort(HashSlice(a))
  52. }
  53. // HashSlice attaches the methods of sort.Interface to []Hash, sorting in
  54. // increasing order.
  55. type HashSlice []Hash
  56. func (p HashSlice) Len() int { return len(p) }
  57. func (p HashSlice) Less(i, j int) bool { return bytes.Compare(p[i][:], p[j][:]) < 0 }
  58. func (p HashSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  59. // IsHash returns true if the given string is a valid hash.
  60. func IsHash(s string) bool {
  61. if len(s) != 40 {
  62. return false
  63. }
  64. _, err := hex.DecodeString(s)
  65. return err == nil
  66. }