github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/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 ) 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 // Its Sum method will lay the value out in big-endian byte order. 31 func New32() hash.Hash32 { 32 var s sum32 = offset32 33 return &s 34 } 35 36 // New32a returns a new 32-bit FNV-1a hash.Hash. 37 // Its Sum method will lay the value out in big-endian byte order. 38 func New32a() hash.Hash32 { 39 var s sum32a = offset32 40 return &s 41 } 42 43 // New64 returns a new 64-bit FNV-1 hash.Hash. 44 // Its Sum method will lay the value out in big-endian byte order. 45 func New64() hash.Hash64 { 46 var s sum64 = offset64 47 return &s 48 } 49 50 // New64a returns a new 64-bit FNV-1a hash.Hash. 51 // Its Sum method will lay the value out in big-endian byte order. 52 func New64a() hash.Hash64 { 53 var s sum64a = offset64 54 return &s 55 } 56 57 func (s *sum32) Reset() { *s = offset32 } 58 func (s *sum32a) Reset() { *s = offset32 } 59 func (s *sum64) Reset() { *s = offset64 } 60 func (s *sum64a) Reset() { *s = offset64 } 61 62 func (s *sum32) Sum32() uint32 { return uint32(*s) } 63 func (s *sum32a) Sum32() uint32 { return uint32(*s) } 64 func (s *sum64) Sum64() uint64 { return uint64(*s) } 65 func (s *sum64a) Sum64() uint64 { return uint64(*s) } 66 67 func (s *sum32) Write(data []byte) (int, error) { 68 hash := *s 69 for _, c := range data { 70 hash *= prime32 71 hash ^= sum32(c) 72 } 73 *s = hash 74 return len(data), nil 75 } 76 77 func (s *sum32a) Write(data []byte) (int, error) { 78 hash := *s 79 for _, c := range data { 80 hash ^= sum32a(c) 81 hash *= prime32 82 } 83 *s = hash 84 return len(data), nil 85 } 86 87 func (s *sum64) Write(data []byte) (int, error) { 88 hash := *s 89 for _, c := range data { 90 hash *= prime64 91 hash ^= sum64(c) 92 } 93 *s = hash 94 return len(data), nil 95 } 96 97 func (s *sum64a) Write(data []byte) (int, error) { 98 hash := *s 99 for _, c := range data { 100 hash ^= sum64a(c) 101 hash *= prime64 102 } 103 *s = hash 104 return len(data), nil 105 } 106 107 func (s *sum32) Size() int { return 4 } 108 func (s *sum32a) Size() int { return 4 } 109 func (s *sum64) Size() int { return 8 } 110 func (s *sum64a) Size() int { return 8 } 111 112 func (s *sum32) BlockSize() int { return 1 } 113 func (s *sum32a) BlockSize() int { return 1 } 114 func (s *sum64) BlockSize() int { return 1 } 115 func (s *sum64a) BlockSize() int { return 1 } 116 117 func (s *sum32) Sum(in []byte) []byte { 118 v := uint32(*s) 119 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 120 } 121 122 func (s *sum32a) Sum(in []byte) []byte { 123 v := uint32(*s) 124 return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) 125 } 126 127 func (s *sum64) Sum(in []byte) []byte { 128 v := uint64(*s) 129 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)) 130 } 131 132 func (s *sum64a) Sum(in []byte) []byte { 133 v := uint64(*s) 134 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)) 135 }