xxh32zero.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Package xxh32 implements the very fast XXH hashing algorithm (32 bits version).
  2. // (https://github.com/Cyan4973/XXH/)
  3. package xxh32
  4. import (
  5. "encoding/binary"
  6. )
  7. const (
  8. prime32_1 uint32 = 2654435761
  9. prime32_2 uint32 = 2246822519
  10. prime32_3 uint32 = 3266489917
  11. prime32_4 uint32 = 668265263
  12. prime32_5 uint32 = 374761393
  13. prime32_1plus2 uint32 = 606290984
  14. prime32_minus1 uint32 = 1640531535
  15. )
  16. // XXHZero represents an xxhash32 object with seed 0.
  17. type XXHZero struct {
  18. v1 uint32
  19. v2 uint32
  20. v3 uint32
  21. v4 uint32
  22. totalLen uint64
  23. buf [16]byte
  24. bufused int
  25. }
  26. // Sum appends the current hash to b and returns the resulting slice.
  27. // It does not change the underlying hash state.
  28. func (xxh XXHZero) Sum(b []byte) []byte {
  29. h32 := xxh.Sum32()
  30. return append(b, byte(h32), byte(h32>>8), byte(h32>>16), byte(h32>>24))
  31. }
  32. // Reset resets the Hash to its initial state.
  33. func (xxh *XXHZero) Reset() {
  34. xxh.v1 = prime32_1plus2
  35. xxh.v2 = prime32_2
  36. xxh.v3 = 0
  37. xxh.v4 = prime32_minus1
  38. xxh.totalLen = 0
  39. xxh.bufused = 0
  40. }
  41. // Size returns the number of bytes returned by Sum().
  42. func (xxh *XXHZero) Size() int {
  43. return 4
  44. }
  45. // BlockSize gives the minimum number of bytes accepted by Write().
  46. func (xxh *XXHZero) BlockSize() int {
  47. return 1
  48. }
  49. // Write adds input bytes to the Hash.
  50. // It never returns an error.
  51. func (xxh *XXHZero) Write(input []byte) (int, error) {
  52. if xxh.totalLen == 0 {
  53. xxh.Reset()
  54. }
  55. n := len(input)
  56. m := xxh.bufused
  57. xxh.totalLen += uint64(n)
  58. r := len(xxh.buf) - m
  59. if n < r {
  60. copy(xxh.buf[m:], input)
  61. xxh.bufused += len(input)
  62. return n, nil
  63. }
  64. p := 0
  65. // Causes compiler to work directly from registers instead of stack:
  66. v1, v2, v3, v4 := xxh.v1, xxh.v2, xxh.v3, xxh.v4
  67. if m > 0 {
  68. // some data left from previous update
  69. copy(xxh.buf[xxh.bufused:], input[:r])
  70. xxh.bufused += len(input) - r
  71. // fast rotl(13)
  72. buf := xxh.buf[:16] // BCE hint.
  73. v1 = rol13(v1+binary.LittleEndian.Uint32(buf[:])*prime32_2) * prime32_1
  74. v2 = rol13(v2+binary.LittleEndian.Uint32(buf[4:])*prime32_2) * prime32_1
  75. v3 = rol13(v3+binary.LittleEndian.Uint32(buf[8:])*prime32_2) * prime32_1
  76. v4 = rol13(v4+binary.LittleEndian.Uint32(buf[12:])*prime32_2) * prime32_1
  77. p = r
  78. xxh.bufused = 0
  79. }
  80. for n := n - 16; p <= n; p += 16 {
  81. sub := input[p:][:16] //BCE hint for compiler
  82. v1 = rol13(v1+binary.LittleEndian.Uint32(sub[:])*prime32_2) * prime32_1
  83. v2 = rol13(v2+binary.LittleEndian.Uint32(sub[4:])*prime32_2) * prime32_1
  84. v3 = rol13(v3+binary.LittleEndian.Uint32(sub[8:])*prime32_2) * prime32_1
  85. v4 = rol13(v4+binary.LittleEndian.Uint32(sub[12:])*prime32_2) * prime32_1
  86. }
  87. xxh.v1, xxh.v2, xxh.v3, xxh.v4 = v1, v2, v3, v4
  88. copy(xxh.buf[xxh.bufused:], input[p:])
  89. xxh.bufused += len(input) - p
  90. return n, nil
  91. }
  92. // Sum32 returns the 32 bits Hash value.
  93. func (xxh *XXHZero) Sum32() uint32 {
  94. h32 := uint32(xxh.totalLen)
  95. if h32 >= 16 {
  96. h32 += rol1(xxh.v1) + rol7(xxh.v2) + rol12(xxh.v3) + rol18(xxh.v4)
  97. } else {
  98. h32 += prime32_5
  99. }
  100. p := 0
  101. n := xxh.bufused
  102. buf := xxh.buf
  103. for n := n - 4; p <= n; p += 4 {
  104. h32 += binary.LittleEndian.Uint32(buf[p:p+4]) * prime32_3
  105. h32 = rol17(h32) * prime32_4
  106. }
  107. for ; p < n; p++ {
  108. h32 += uint32(buf[p]) * prime32_5
  109. h32 = rol11(h32) * prime32_1
  110. }
  111. h32 ^= h32 >> 15
  112. h32 *= prime32_2
  113. h32 ^= h32 >> 13
  114. h32 *= prime32_3
  115. h32 ^= h32 >> 16
  116. return h32
  117. }
  118. // ChecksumZero returns the 32bits Hash value.
  119. func ChecksumZero(input []byte) uint32 {
  120. n := len(input)
  121. h32 := uint32(n)
  122. if n < 16 {
  123. h32 += prime32_5
  124. } else {
  125. v1 := prime32_1plus2
  126. v2 := prime32_2
  127. v3 := uint32(0)
  128. v4 := prime32_minus1
  129. p := 0
  130. for n := n - 16; p <= n; p += 16 {
  131. sub := input[p:][:16] //BCE hint for compiler
  132. v1 = rol13(v1+binary.LittleEndian.Uint32(sub[:])*prime32_2) * prime32_1
  133. v2 = rol13(v2+binary.LittleEndian.Uint32(sub[4:])*prime32_2) * prime32_1
  134. v3 = rol13(v3+binary.LittleEndian.Uint32(sub[8:])*prime32_2) * prime32_1
  135. v4 = rol13(v4+binary.LittleEndian.Uint32(sub[12:])*prime32_2) * prime32_1
  136. }
  137. input = input[p:]
  138. n -= p
  139. h32 += rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)
  140. }
  141. p := 0
  142. for n := n - 4; p <= n; p += 4 {
  143. h32 += binary.LittleEndian.Uint32(input[p:p+4]) * prime32_3
  144. h32 = rol17(h32) * prime32_4
  145. }
  146. for p < n {
  147. h32 += uint32(input[p]) * prime32_5
  148. h32 = rol11(h32) * prime32_1
  149. p++
  150. }
  151. h32 ^= h32 >> 15
  152. h32 *= prime32_2
  153. h32 ^= h32 >> 13
  154. h32 *= prime32_3
  155. h32 ^= h32 >> 16
  156. return h32
  157. }
  158. // Uint32Zero hashes x with seed 0.
  159. func Uint32Zero(x uint32) uint32 {
  160. h := prime32_5 + 4 + x*prime32_3
  161. h = rol17(h) * prime32_4
  162. h ^= h >> 15
  163. h *= prime32_2
  164. h ^= h >> 13
  165. h *= prime32_3
  166. h ^= h >> 16
  167. return h
  168. }
  169. func rol1(u uint32) uint32 {
  170. return u<<1 | u>>31
  171. }
  172. func rol7(u uint32) uint32 {
  173. return u<<7 | u>>25
  174. }
  175. func rol11(u uint32) uint32 {
  176. return u<<11 | u>>21
  177. }
  178. func rol12(u uint32) uint32 {
  179. return u<<12 | u>>20
  180. }
  181. func rol13(u uint32) uint32 {
  182. return u<<13 | u>>19
  183. }
  184. func rol17(u uint32) uint32 {
  185. return u<<17 | u>>15
  186. }
  187. func rol18(u uint32) uint32 {
  188. return u<<18 | u>>14
  189. }