Daily bump.
[official-gcc.git] / libgo / go / hash / fnv / fnv.go
blob0fce177cb33798685006bc165387e43bd40ec680
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.
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 //
10 // All the hash.Hash implementations returned by this package also
11 // implement encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
12 // marshal and unmarshal the internal state of the hash.
13 package fnv
15 import (
16 "errors"
17 "hash"
18 "math/bits"
21 type (
22 sum32 uint32
23 sum32a uint32
24 sum64 uint64
25 sum64a uint64
26 sum128 [2]uint64
27 sum128a [2]uint64
30 const (
31 offset32 = 2166136261
32 offset64 = 14695981039346656037
33 offset128Lower = 0x62b821756295c58d
34 offset128Higher = 0x6c62272e07bb0142
35 prime32 = 16777619
36 prime64 = 1099511628211
37 prime128Lower = 0x13b
38 prime128Shift = 24
41 // New32 returns a new 32-bit FNV-1 hash.Hash.
42 // Its Sum method will lay the value out in big-endian byte order.
43 func New32() hash.Hash32 {
44 var s sum32 = offset32
45 return &s
48 // New32a returns a new 32-bit FNV-1a hash.Hash.
49 // Its Sum method will lay the value out in big-endian byte order.
50 func New32a() hash.Hash32 {
51 var s sum32a = offset32
52 return &s
55 // New64 returns a new 64-bit FNV-1 hash.Hash.
56 // Its Sum method will lay the value out in big-endian byte order.
57 func New64() hash.Hash64 {
58 var s sum64 = offset64
59 return &s
62 // New64a returns a new 64-bit FNV-1a hash.Hash.
63 // Its Sum method will lay the value out in big-endian byte order.
64 func New64a() hash.Hash64 {
65 var s sum64a = offset64
66 return &s
69 // New128 returns a new 128-bit FNV-1 hash.Hash.
70 // Its Sum method will lay the value out in big-endian byte order.
71 func New128() hash.Hash {
72 var s sum128
73 s[0] = offset128Higher
74 s[1] = offset128Lower
75 return &s
78 // New128a returns a new 128-bit FNV-1a hash.Hash.
79 // Its Sum method will lay the value out in big-endian byte order.
80 func New128a() hash.Hash {
81 var s sum128a
82 s[0] = offset128Higher
83 s[1] = offset128Lower
84 return &s
87 func (s *sum32) Reset() { *s = offset32 }
88 func (s *sum32a) Reset() { *s = offset32 }
89 func (s *sum64) Reset() { *s = offset64 }
90 func (s *sum64a) Reset() { *s = offset64 }
91 func (s *sum128) Reset() { s[0] = offset128Higher; s[1] = offset128Lower }
92 func (s *sum128a) Reset() { s[0] = offset128Higher; s[1] = offset128Lower }
94 func (s *sum32) Sum32() uint32 { return uint32(*s) }
95 func (s *sum32a) Sum32() uint32 { return uint32(*s) }
96 func (s *sum64) Sum64() uint64 { return uint64(*s) }
97 func (s *sum64a) Sum64() uint64 { return uint64(*s) }
99 func (s *sum32) Write(data []byte) (int, error) {
100 hash := *s
101 for _, c := range data {
102 hash *= prime32
103 hash ^= sum32(c)
105 *s = hash
106 return len(data), nil
109 func (s *sum32a) Write(data []byte) (int, error) {
110 hash := *s
111 for _, c := range data {
112 hash ^= sum32a(c)
113 hash *= prime32
115 *s = hash
116 return len(data), nil
119 func (s *sum64) Write(data []byte) (int, error) {
120 hash := *s
121 for _, c := range data {
122 hash *= prime64
123 hash ^= sum64(c)
125 *s = hash
126 return len(data), nil
129 func (s *sum64a) Write(data []byte) (int, error) {
130 hash := *s
131 for _, c := range data {
132 hash ^= sum64a(c)
133 hash *= prime64
135 *s = hash
136 return len(data), nil
139 func (s *sum128) Write(data []byte) (int, error) {
140 for _, c := range data {
141 // Compute the multiplication
142 s0, s1 := bits.Mul64(prime128Lower, s[1])
143 s0 += s[1]<<prime128Shift + prime128Lower*s[0]
144 // Update the values
145 s[1] = s1
146 s[0] = s0
147 s[1] ^= uint64(c)
149 return len(data), nil
152 func (s *sum128a) Write(data []byte) (int, error) {
153 for _, c := range data {
154 s[1] ^= uint64(c)
155 // Compute the multiplication
156 s0, s1 := bits.Mul64(prime128Lower, s[1])
157 s0 += s[1]<<prime128Shift + prime128Lower*s[0]
158 // Update the values
159 s[1] = s1
160 s[0] = s0
162 return len(data), nil
165 func (s *sum32) Size() int { return 4 }
166 func (s *sum32a) Size() int { return 4 }
167 func (s *sum64) Size() int { return 8 }
168 func (s *sum64a) Size() int { return 8 }
169 func (s *sum128) Size() int { return 16 }
170 func (s *sum128a) Size() int { return 16 }
172 func (s *sum32) BlockSize() int { return 1 }
173 func (s *sum32a) BlockSize() int { return 1 }
174 func (s *sum64) BlockSize() int { return 1 }
175 func (s *sum64a) BlockSize() int { return 1 }
176 func (s *sum128) BlockSize() int { return 1 }
177 func (s *sum128a) BlockSize() int { return 1 }
179 func (s *sum32) Sum(in []byte) []byte {
180 v := uint32(*s)
181 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
184 func (s *sum32a) Sum(in []byte) []byte {
185 v := uint32(*s)
186 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
189 func (s *sum64) Sum(in []byte) []byte {
190 v := uint64(*s)
191 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))
194 func (s *sum64a) Sum(in []byte) []byte {
195 v := uint64(*s)
196 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))
199 func (s *sum128) Sum(in []byte) []byte {
200 return append(in,
201 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]),
202 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]),
206 func (s *sum128a) Sum(in []byte) []byte {
207 return append(in,
208 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]),
209 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]),
213 const (
214 magic32 = "fnv\x01"
215 magic32a = "fnv\x02"
216 magic64 = "fnv\x03"
217 magic64a = "fnv\x04"
218 magic128 = "fnv\x05"
219 magic128a = "fnv\x06"
220 marshaledSize32 = len(magic32) + 4
221 marshaledSize64 = len(magic64) + 8
222 marshaledSize128 = len(magic128) + 8*2
225 func (s *sum32) MarshalBinary() ([]byte, error) {
226 b := make([]byte, 0, marshaledSize32)
227 b = append(b, magic32...)
228 b = appendUint32(b, uint32(*s))
229 return b, nil
232 func (s *sum32a) MarshalBinary() ([]byte, error) {
233 b := make([]byte, 0, marshaledSize32)
234 b = append(b, magic32a...)
235 b = appendUint32(b, uint32(*s))
236 return b, nil
239 func (s *sum64) MarshalBinary() ([]byte, error) {
240 b := make([]byte, 0, marshaledSize64)
241 b = append(b, magic64...)
242 b = appendUint64(b, uint64(*s))
243 return b, nil
247 func (s *sum64a) MarshalBinary() ([]byte, error) {
248 b := make([]byte, 0, marshaledSize64)
249 b = append(b, magic64a...)
250 b = appendUint64(b, uint64(*s))
251 return b, nil
254 func (s *sum128) MarshalBinary() ([]byte, error) {
255 b := make([]byte, 0, marshaledSize128)
256 b = append(b, magic128...)
257 b = appendUint64(b, s[0])
258 b = appendUint64(b, s[1])
259 return b, nil
262 func (s *sum128a) MarshalBinary() ([]byte, error) {
263 b := make([]byte, 0, marshaledSize128)
264 b = append(b, magic128a...)
265 b = appendUint64(b, s[0])
266 b = appendUint64(b, s[1])
267 return b, nil
270 func (s *sum32) UnmarshalBinary(b []byte) error {
271 if len(b) < len(magic32) || string(b[:len(magic32)]) != magic32 {
272 return errors.New("hash/fnv: invalid hash state identifier")
274 if len(b) != marshaledSize32 {
275 return errors.New("hash/fnv: invalid hash state size")
277 *s = sum32(readUint32(b[4:]))
278 return nil
281 func (s *sum32a) UnmarshalBinary(b []byte) error {
282 if len(b) < len(magic32a) || string(b[:len(magic32a)]) != magic32a {
283 return errors.New("hash/fnv: invalid hash state identifier")
285 if len(b) != marshaledSize32 {
286 return errors.New("hash/fnv: invalid hash state size")
288 *s = sum32a(readUint32(b[4:]))
289 return nil
292 func (s *sum64) UnmarshalBinary(b []byte) error {
293 if len(b) < len(magic64) || string(b[:len(magic64)]) != magic64 {
294 return errors.New("hash/fnv: invalid hash state identifier")
296 if len(b) != marshaledSize64 {
297 return errors.New("hash/fnv: invalid hash state size")
299 *s = sum64(readUint64(b[4:]))
300 return nil
303 func (s *sum64a) UnmarshalBinary(b []byte) error {
304 if len(b) < len(magic64a) || string(b[:len(magic64a)]) != magic64a {
305 return errors.New("hash/fnv: invalid hash state identifier")
307 if len(b) != marshaledSize64 {
308 return errors.New("hash/fnv: invalid hash state size")
310 *s = sum64a(readUint64(b[4:]))
311 return nil
314 func (s *sum128) UnmarshalBinary(b []byte) error {
315 if len(b) < len(magic128) || string(b[:len(magic128)]) != magic128 {
316 return errors.New("hash/fnv: invalid hash state identifier")
318 if len(b) != marshaledSize128 {
319 return errors.New("hash/fnv: invalid hash state size")
321 s[0] = readUint64(b[4:])
322 s[1] = readUint64(b[12:])
323 return nil
326 func (s *sum128a) UnmarshalBinary(b []byte) error {
327 if len(b) < len(magic128a) || string(b[:len(magic128a)]) != magic128a {
328 return errors.New("hash/fnv: invalid hash state identifier")
330 if len(b) != marshaledSize128 {
331 return errors.New("hash/fnv: invalid hash state size")
333 s[0] = readUint64(b[4:])
334 s[1] = readUint64(b[12:])
335 return nil
338 func readUint32(b []byte) uint32 {
339 _ = b[3]
340 return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
343 func appendUint32(b []byte, x uint32) []byte {
344 a := [4]byte{
345 byte(x >> 24),
346 byte(x >> 16),
347 byte(x >> 8),
348 byte(x),
350 return append(b, a[:]...)
353 func appendUint64(b []byte, x uint64) []byte {
354 a := [8]byte{
355 byte(x >> 56),
356 byte(x >> 48),
357 byte(x >> 40),
358 byte(x >> 32),
359 byte(x >> 24),
360 byte(x >> 16),
361 byte(x >> 8),
362 byte(x),
364 return append(b, a[:]...)
367 func readUint64(b []byte) uint64 {
368 _ = b[7]
369 return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
370 uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56