Source file src/pkg/hash/fnv/fnv.go
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 http://isthe.com/chongo/tech/comp/fnv/.
8 package fnv
9
10 import (
11 "hash"
12 )
13
14 type (
15 sum32 uint32
16 sum32a uint32
17 sum64 uint64
18 sum64a uint64
19 )
20
21 const (
22 offset32 = 2166136261
23 offset64 = 14695981039346656037
24 prime32 = 16777619
25 prime64 = 1099511628211
26 )
27
28 // New32 returns a new 32-bit FNV-1 hash.Hash.
29 func New32() hash.Hash32 {
30 var s sum32 = offset32
31 return &s
32 }
33
34 // New32a returns a new 32-bit FNV-1a hash.Hash.
35 func New32a() hash.Hash32 {
36 var s sum32a = offset32
37 return &s
38 }
39
40 // New64 returns a new 64-bit FNV-1 hash.Hash.
41 func New64() hash.Hash64 {
42 var s sum64 = offset64
43 return &s
44 }
45
46 // New64a returns a new 64-bit FNV-1a hash.Hash.
47 func New64a() hash.Hash64 {
48 var s sum64a = offset64
49 return &s
50 }
51
52 func (s *sum32) Reset() { *s = offset32 }
53 func (s *sum32a) Reset() { *s = offset32 }
54 func (s *sum64) Reset() { *s = offset64 }
55 func (s *sum64a) Reset() { *s = offset64 }
56
57 func (s *sum32) Sum32() uint32 { return uint32(*s) }
58 func (s *sum32a) Sum32() uint32 { return uint32(*s) }
59 func (s *sum64) Sum64() uint64 { return uint64(*s) }
60 func (s *sum64a) Sum64() uint64 { return uint64(*s) }
61
62 func (s *sum32) Write(data []byte) (int, error) {
63 hash := *s
64 for _, c := range data {
65 hash *= prime32
66 hash ^= sum32(c)
67 }
68 *s = hash
69 return len(data), nil
70 }
71
72 func (s *sum32a) Write(data []byte) (int, error) {
73 hash := *s
74 for _, c := range data {
75 hash ^= sum32a(c)
76 hash *= prime32
77 }
78 *s = hash
79 return len(data), nil
80 }
81
82 func (s *sum64) Write(data []byte) (int, error) {
83 hash := *s
84 for _, c := range data {
85 hash *= prime64
86 hash ^= sum64(c)
87 }
88 *s = hash
89 return len(data), nil
90 }
91
92 func (s *sum64a) Write(data []byte) (int, error) {
93 hash := *s
94 for _, c := range data {
95 hash ^= sum64a(c)
96 hash *= prime64
97 }
98 *s = hash
99 return len(data), nil
100 }
101
102 func (s *sum32) Size() int { return 4 }
103 func (s *sum32a) Size() int { return 4 }
104 func (s *sum64) Size() int { return 8 }
105 func (s *sum64a) Size() int { return 8 }
106
107 func (s *sum32) BlockSize() int { return 1 }
108 func (s *sum32a) BlockSize() int { return 1 }
109 func (s *sum64) BlockSize() int { return 1 }
110 func (s *sum64a) BlockSize() int { return 1 }
111
112 func (s *sum32) Sum(in []byte) []byte {
113 v := uint32(*s)
114 in = append(in, byte(v>>24))
115 in = append(in, byte(v>>16))
116 in = append(in, byte(v>>8))
117 in = append(in, byte(v))
118 return in
119 }
120
121 func (s *sum32a) Sum(in []byte) []byte {
122 v := uint32(*s)
123 in = append(in, byte(v>>24))
124 in = append(in, byte(v>>16))
125 in = append(in, byte(v>>8))
126 in = append(in, byte(v))
127 return in
128 }
129
130 func (s *sum64) Sum(in []byte) []byte {
131 v := uint64(*s)
132 in = append(in, byte(v>>56))
133 in = append(in, byte(v>>48))
134 in = append(in, byte(v>>40))
135 in = append(in, byte(v>>32))
136 in = append(in, byte(v>>24))
137 in = append(in, byte(v>>16))
138 in = append(in, byte(v>>8))
139 in = append(in, byte(v))
140 return in
141 }
142
143 func (s *sum64a) Sum(in []byte) []byte {
144 v := uint64(*s)
145 in = append(in, byte(v>>56))
146 in = append(in, byte(v>>48))
147 in = append(in, byte(v>>40))
148 in = append(in, byte(v>>32))
149 in = append(in, byte(v>>24))
150 in = append(in, byte(v>>16))
151 in = append(in, byte(v>>8))
152 in = append(in, byte(v))
153 return in
154 }