github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/hash/fnv/fnv.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package fnv implements FNV-1 and FNV-1a, non-cryptographic hash functions 6 // created by Glenn Fowler, Landon Curt Noll, and Phong Vo. 7 // See 8 // https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function. 9 package fnv 10 11 import ( 12 "hash" 13 ) 14 15 type ( 16 sum32 uint32 17 sum32a uint32 18 sum64 uint64 19 sum64a uint64 20 sum128 [2]uint64 21 sum128a [2]uint64 22 ) 23 24 const ( 25 offset32 = 2166136261 26 offset64 = 14695981039346656037 27 offset128Lower = 0x62b821756295c58d 28 offset128Higher = 0x6c62272e07bb0142 29 prime32 = 16777619 30 prime64 = 1099511628211 31 prime128Lower = 0x13b 32 prime128Shift = 24 33 ) 34 35 // New32 returns a new 32-bit FNV-1 hash.Hash. 36 // Its Sum method will lay the value out in big-endian byte order. 37 func New32() hash.Hash32 { 38 var s sum32 = offset32 39 return &s 40 } 41 42 // New32a returns a new 32-bit FNV-1a hash.Hash. 43 // Its Sum method will lay the value out in big-endian byte order. 44 func New32a() hash.Hash32 { 45 var s sum32a = offset32 46 return &s 47 } 48 49 // New64 returns a new 64-bit FNV-1 hash.Hash. 50 // Its Sum method will lay the value out in big-endian byte order. 51 func New64() hash.Hash64 { 52 var s sum64 = offset64 53 return &s 54 } 55 56 // New64a returns a new 64-bit FNV-1a hash.Hash. 57 // Its Sum method will lay the value out in big-endian byte order. 58 func New64a() hash.Hash64 { 59 var s sum64a = offset64 60 return &s 61 } 62 63 // New128 returns a new 128-bit FNV-1 hash.Hash. 64 // Its Sum method will lay the value out in big-endian byte order. 65 func New128() hash.Hash { 66 var s sum128 67 s[0] = offset128Higher 68 s[1] = offset128Lower 69 return &s 70 } 71 72 // New128a returns a new 128-bit FNV-1a hash.Hash. 73 // Its Sum method will lay the value out in big-endian byte order. 74 func New128a() hash.Hash { 75 var s sum128a 76 s[0] = offset128Higher 77 s[1] = offset128Lower 78 return &s 79 } 80 81 func (s *sum32) Reset() { *s = offset32 } 82 func (s *sum32a) Reset() { *s = offset32 } 83 func (s *sum64) Reset() { *s = offset64 } 84 func (s *sum64a) Reset() { *s = offset64 } 85 func (s *sum128) Reset() { s[0] = offset128Higher; s[1] = offset128Lower } 86 func (s *sum128a) Reset() { s[0] = offset128Higher; s[1] = offset128Lower } 87 88 func (s *sum32) Sum32() uint32 { return uint32(*s) } 89 func (s *sum32a) Sum32() uint32 { return uint32(*s) } 90 func (s *sum64) Sum64() uint64 { return uint64(*s) } 91 func (s *sum64a) Sum64() uint64 { return uint64(*s) } 92 93 func (s *sum32) Write(data []byte) (int, error) { 94 hash := *s 95 for _, c := range data { 96 hash *= prime32 97 hash ^= sum32(c) 98 } 99 *s = hash 100 return len(data), nil 101 } 102 103 func (s *sum32a) Write(data []byte) (int, error) { 104 hash := *s 105 for _, c := range data { 106 hash ^= sum32a(c) 107 hash *= prime32 108 } 109 *s = hash 110 return len(data), nil 111 } 112 113 func (s *sum64) Write(data []byte) (int, error) { 114 hash := *s 115 for _, c := range data { 116 hash *= prime64 117 hash ^= sum64(c) 118 } 119 *s = hash 120 return len(data), nil 121 } 122 123 func (s *sum64a) Write(data []byte) (int, error) { 124 hash := *s 125 for _, c := range data { 126 hash ^= sum64a(c) 127 hash *= prime64 128 } 129 *s = hash 130 return len(data), nil 131 } 132 133 func (s *sum128) Write(data []byte) (int, error) { 134 for _, c := range data { 135 // Compute the multiplication in 4 parts to simplify carrying 136 s1l := (s[1] & 0xffffffff) * prime128Lower 137 s1h := (s[1] >> 32) * prime128Lower 138 s0l := (s[0]&0xffffffff)*prime128Lower + (s[1]&0xffffffff)<<prime128Shift 139 s0h := (s[0]>>32)*prime128Lower + (s[1]>>32)<<prime128Shift 140 // Carries 141 s1h += s1l >> 32 142 s0l += s1h >> 32 143 s0h += s0l >> 32 144 // Update the values 145 s[1] = (s1l & 0xffffffff) + (s1h << 32) 146 s[0] = (s0l & 0xffffffff) + (s0h << 32) 147 s[1] ^= uint64(c) 148 } 149 return len(data), nil 150 } 151 152 func (s *sum128a) Write(data []byte) (int, error) { 153 for _, c := range data { 154 s[1] ^= uint64(c) 155 // Compute the multiplication in 4 parts to simplify carrying 156 s1l := (s[1] & 0xffffffff) * prime128Lower 157 s1h := (s[1] >> 32) * prime128Lower 158 s0l := (s[0]&0xffffffff)*prime128Lower + (s[1]&0xffffffff)<<prime128Shift 159 s0h := (s[0]>>32)*prime128Lower + (s[1]>>32)<<prime128Shift 160 // Carries 161 s1h += s1l >> 32 162 s0l += s1h >> 32 163 s0h += s0l >> 32 164 // Update the values 165 s[1] = (s1l & 0xffffffff) + (s1h << 32) 166 s[0] = (s0l & 0xffffffff) + (s0h << 32) 167 } 168 return len(data), nil 169 } 170 171 func (s *sum32) Size() int { return 4 } 172 func (s *sum32a) Size() int { return 4 } 173 func (s *sum64) Size() int { return 8 } 174 func (s *sum64a) Size() int { return 8 } 175 func (s *sum128) Size() int { return 16 } 176 func (s *sum128a) Size() int { return 16 } 177 178 func (s *sum32) BlockSize() int { return 1 } 179 func (s *sum32a) BlockSize() int { return 1 } 180 func (s *sum64) BlockSize() int { return 1 } 181 func (s *sum64a) BlockSize() int { return 1 } 182 func (s *sum128) BlockSize() int { return 1 } 183 func (s *sum128a) BlockSize() int { return 1 } 184 185 func (s *sum32) Sum(in []byte) []byte { 186 v := uint32(*s) 187 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 188 } 189 190 func (s *sum32a) Sum(in []byte) []byte { 191 v := uint32(*s) 192 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 193 } 194 195 func (s *sum64) Sum(in []byte) []byte { 196 v := uint64(*s) 197 return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 198 } 199 200 func (s *sum64a) Sum(in []byte) []byte { 201 v := uint64(*s) 202 return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 203 } 204 205 func (s *sum128) Sum(in []byte) []byte { 206 return append(in, 207 byte(s[0]>>56), byte(s[0]>>48), byte(s[0]>>40), byte(s[0]>>32), byte(s[0]>>24), byte(s[0]>>16), byte(s[0]>>8), byte(s[0]), 208 byte(s[1]>>56), byte(s[1]>>48), byte(s[1]>>40), byte(s[1]>>32), byte(s[1]>>24), byte(s[1]>>16), byte(s[1]>>8), byte(s[1]), 209 ) 210 } 211 212 func (s *sum128a) Sum(in []byte) []byte { 213 return append(in, 214 byte(s[0]>>56), byte(s[0]>>48), byte(s[0]>>40), byte(s[0]>>32), byte(s[0]>>24), byte(s[0]>>16), byte(s[0]>>8), byte(s[0]), 215 byte(s[1]>>56), byte(s[1]>>48), byte(s[1]>>40), byte(s[1]>>32), byte(s[1]>>24), byte(s[1]>>16), byte(s[1]>>8), byte(s[1]), 216 ) 217 }