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  }