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 // http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_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 ) 21 22 const ( 23 offset32 = 2166136261 24 offset64 = 14695981039346656037 25 prime32 = 16777619 26 prime64 = 1099511628211 27 ) 28 29 // New32 returns a new 32-bit FNV-1 hash.Hash. 30 func New32() hash.Hash32 { 31 var s sum32 = offset32 32 return &s 33 } 34 35 // New32a returns a new 32-bit FNV-1a hash.Hash. 36 func New32a() hash.Hash32 { 37 var s sum32a = offset32 38 return &s 39 } 40 41 // New64 returns a new 64-bit FNV-1 hash.Hash. 42 func New64() hash.Hash64 { 43 var s sum64 = offset64 44 return &s 45 } 46 47 // New64a returns a new 64-bit FNV-1a hash.Hash. 48 func New64a() hash.Hash64 { 49 var s sum64a = offset64 50 return &s 51 } 52 53 func (s *sum32) Reset() { *s = offset32 } 54 func (s *sum32a) Reset() { *s = offset32 } 55 func (s *sum64) Reset() { *s = offset64 } 56 func (s *sum64a) Reset() { *s = offset64 } 57 58 func (s *sum32) Sum32() uint32 { return uint32(*s) } 59 func (s *sum32a) Sum32() uint32 { return uint32(*s) } 60 func (s *sum64) Sum64() uint64 { return uint64(*s) } 61 func (s *sum64a) Sum64() uint64 { return uint64(*s) } 62 63 func (s *sum32) Write(data []byte) (int, error) { 64 hash := *s 65 for _, c := range data { 66 hash *= prime32 67 hash ^= sum32(c) 68 } 69 *s = hash 70 return len(data), nil 71 } 72 73 func (s *sum32a) Write(data []byte) (int, error) { 74 hash := *s 75 for _, c := range data { 76 hash ^= sum32a(c) 77 hash *= prime32 78 } 79 *s = hash 80 return len(data), nil 81 } 82 83 func (s *sum64) Write(data []byte) (int, error) { 84 hash := *s 85 for _, c := range data { 86 hash *= prime64 87 hash ^= sum64(c) 88 } 89 *s = hash 90 return len(data), nil 91 } 92 93 func (s *sum64a) Write(data []byte) (int, error) { 94 hash := *s 95 for _, c := range data { 96 hash ^= sum64a(c) 97 hash *= prime64 98 } 99 *s = hash 100 return len(data), nil 101 } 102 103 func (s *sum32) Size() int { return 4 } 104 func (s *sum32a) Size() int { return 4 } 105 func (s *sum64) Size() int { return 8 } 106 func (s *sum64a) Size() int { return 8 } 107 108 func (s *sum32) BlockSize() int { return 1 } 109 func (s *sum32a) BlockSize() int { return 1 } 110 func (s *sum64) BlockSize() int { return 1 } 111 func (s *sum64a) BlockSize() int { return 1 } 112 113 func (s *sum32) Sum(in []byte) []byte { 114 v := uint32(*s) 115 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 116 } 117 118 func (s *sum32a) Sum(in []byte) []byte { 119 v := uint32(*s) 120 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 121 } 122 123 func (s *sum64) Sum(in []byte) []byte { 124 v := uint64(*s) 125 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)) 126 } 127 128 func (s *sum64a) Sum(in []byte) []byte { 129 v := uint64(*s) 130 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)) 131 } 132