您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

object_format.go 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package git
  4. import (
  5. "crypto/sha1"
  6. "crypto/sha256"
  7. "regexp"
  8. "strconv"
  9. )
  10. // sha1Pattern can be used to determine if a string is an valid sha
  11. var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`)
  12. // sha256Pattern can be used to determine if a string is an valid sha
  13. var sha256Pattern = regexp.MustCompile(`^[0-9a-f]{4,64}$`)
  14. type ObjectFormat interface {
  15. // Name returns the name of the object format
  16. Name() string
  17. // EmptyObjectID creates a new empty ObjectID from an object format hash name
  18. EmptyObjectID() ObjectID
  19. // EmptyTree is the hash of an empty tree
  20. EmptyTree() ObjectID
  21. // FullLength is the length of the hash's hex string
  22. FullLength() int
  23. // IsValid returns true if the input is a valid hash
  24. IsValid(input string) bool
  25. // MustID creates a new ObjectID from a byte slice
  26. MustID(b []byte) ObjectID
  27. // ComputeHash compute the hash for a given ObjectType and content
  28. ComputeHash(t ObjectType, content []byte) ObjectID
  29. }
  30. type Sha1ObjectFormatImpl struct{}
  31. var (
  32. emptySha1ObjectID = &Sha1Hash{}
  33. emptySha1Tree = &Sha1Hash{
  34. 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
  35. 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04,
  36. }
  37. )
  38. func (Sha1ObjectFormatImpl) Name() string { return "sha1" }
  39. func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID {
  40. return emptySha1ObjectID
  41. }
  42. func (Sha1ObjectFormatImpl) EmptyTree() ObjectID {
  43. return emptySha1Tree
  44. }
  45. func (Sha1ObjectFormatImpl) FullLength() int { return 40 }
  46. func (Sha1ObjectFormatImpl) IsValid(input string) bool {
  47. return sha1Pattern.MatchString(input)
  48. }
  49. func (Sha1ObjectFormatImpl) MustID(b []byte) ObjectID {
  50. var id Sha1Hash
  51. copy(id[0:20], b)
  52. return &id
  53. }
  54. // ComputeHash compute the hash for a given ObjectType and content
  55. func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
  56. hasher := sha1.New()
  57. _, _ = hasher.Write(t.Bytes())
  58. _, _ = hasher.Write([]byte(" "))
  59. _, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
  60. _, _ = hasher.Write([]byte{0})
  61. _, _ = hasher.Write(content)
  62. return h.MustID(hasher.Sum(nil))
  63. }
  64. type Sha256ObjectFormatImpl struct{}
  65. var (
  66. emptySha256ObjectID = &Sha256Hash{}
  67. emptySha256Tree = &Sha256Hash{
  68. 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1,
  69. 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5,
  70. 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc,
  71. 0x53, 0x21,
  72. }
  73. )
  74. func (Sha256ObjectFormatImpl) Name() string { return "sha256" }
  75. func (Sha256ObjectFormatImpl) EmptyObjectID() ObjectID {
  76. return emptySha256ObjectID
  77. }
  78. func (Sha256ObjectFormatImpl) EmptyTree() ObjectID {
  79. return emptySha256Tree
  80. }
  81. func (Sha256ObjectFormatImpl) FullLength() int { return 64 }
  82. func (Sha256ObjectFormatImpl) IsValid(input string) bool {
  83. return sha256Pattern.MatchString(input)
  84. }
  85. func (Sha256ObjectFormatImpl) MustID(b []byte) ObjectID {
  86. var id Sha256Hash
  87. copy(id[0:32], b)
  88. return &id
  89. }
  90. // ComputeHash compute the hash for a given ObjectType and content
  91. func (h Sha256ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID {
  92. hasher := sha256.New()
  93. _, _ = hasher.Write(t.Bytes())
  94. _, _ = hasher.Write([]byte(" "))
  95. _, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10)))
  96. _, _ = hasher.Write([]byte{0})
  97. _, _ = hasher.Write(content)
  98. return h.MustID(hasher.Sum(nil))
  99. }
  100. var (
  101. Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{}
  102. Sha256ObjectFormat ObjectFormat = Sha256ObjectFormatImpl{}
  103. )
  104. var SupportedObjectFormats = []ObjectFormat{
  105. Sha1ObjectFormat,
  106. }
  107. func ObjectFormatFromName(name string) ObjectFormat {
  108. for _, objectFormat := range SupportedObjectFormats {
  109. if name == objectFormat.Name() {
  110. return objectFormat
  111. }
  112. }
  113. return nil
  114. }
  115. func IsValidObjectFormat(name string) bool {
  116. return ObjectFormatFromName(name) != nil
  117. }