github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/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  	sum128  [2]uint64
    21  	sum128a [2]uint64
    22  )
    23  
    24  const (
    25  	offset32        = 2166136261
    26  	offset64        = 14695981039346656037
    27  	offset128Lower  = 0x62b821756295c58d
    28  	offset128Higher = 0x6c62272e07bb0142
    29  	prime32         = 16777619
    30  	prime64         = 1099511628211
    31  	prime128Lower   = 0x13b
    32  	prime128Shift   = 24
    33  )
    34  
    35  // New32 returns a new 32-bit FNV-1 hash.Hash.
    36  // Its Sum method will lay the value out in big-endian byte order.
    37  func New32() hash.Hash32 {
    38  	var s sum32 = offset32
    39  	return &s
    40  }
    41  
    42  // New32a returns a new 32-bit FNV-1a hash.Hash.
    43  // Its Sum method will lay the value out in big-endian byte order.
    44  func New32a() hash.Hash32 {
    45  	var s sum32a = offset32
    46  	return &s
    47  }
    48  
    49  // New64 returns a new 64-bit FNV-1 hash.Hash.
    50  // Its Sum method will lay the value out in big-endian byte order.
    51  func New64() hash.Hash64 {
    52  	var s sum64 = offset64
    53  	return &s
    54  }
    55  
    56  // New64a returns a new 64-bit FNV-1a hash.Hash.
    57  // Its Sum method will lay the value out in big-endian byte order.
    58  func New64a() hash.Hash64 {
    59  	var s sum64a = offset64
    60  	return &s
    61  }
    62  
    63  // New128 returns a new 128-bit FNV-1 hash.Hash.
    64  // Its Sum method will lay the value out in big-endian byte order.
    65  func New128() hash.Hash {
    66  	var s sum128
    67  	s[0] = offset128Higher
    68  	s[1] = offset128Lower
    69  	return &s
    70  }
    71  
    72  // New128a returns a new 128-bit FNV-1a hash.Hash.
    73  // Its Sum method will lay the value out in big-endian byte order.
    74  func New128a() hash.Hash {
    75  	var s sum128a
    76  	s[0] = offset128Higher
    77  	s[1] = offset128Lower
    78  	return &s
    79  }
    80  
    81  func (s *sum32) Reset()   { *s = offset32 }
    82  func (s *sum32a) Reset()  { *s = offset32 }
    83  func (s *sum64) Reset()   { *s = offset64 }
    84  func (s *sum64a) Reset()  { *s = offset64 }
    85  func (s *sum128) Reset()  { s[0] = offset128Higher; s[1] = offset128Lower }
    86  func (s *sum128a) Reset() { s[0] = offset128Higher; s[1] = offset128Lower }
    87  
    88  func (s *sum32) Sum32() uint32  { return uint32(*s) }
    89  func (s *sum32a) Sum32() uint32 { return uint32(*s) }
    90  func (s *sum64) Sum64() uint64  { return uint64(*s) }
    91  func (s *sum64a) Sum64() uint64 { return uint64(*s) }
    92  
    93  func (s *sum32) Write(data []byte) (int, error) {
    94  	hash := *s
    95  	for _, c := range data {
    96  		hash *= prime32
    97  		hash ^= sum32(c)
    98  	}
    99  	*s = hash
   100  	return len(data), nil
   101  }
   102  
   103  func (s *sum32a) Write(data []byte) (int, error) {
   104  	hash := *s
   105  	for _, c := range data {
   106  		hash ^= sum32a(c)
   107  		hash *= prime32
   108  	}
   109  	*s = hash
   110  	return len(data), nil
   111  }
   112  
   113  func (s *sum64) Write(data []byte) (int, error) {
   114  	hash := *s
   115  	for _, c := range data {
   116  		hash *= prime64
   117  		hash ^= sum64(c)
   118  	}
   119  	*s = hash
   120  	return len(data), nil
   121  }
   122  
   123  func (s *sum64a) Write(data []byte) (int, error) {
   124  	hash := *s
   125  	for _, c := range data {
   126  		hash ^= sum64a(c)
   127  		hash *= prime64
   128  	}
   129  	*s = hash
   130  	return len(data), nil
   131  }
   132  
   133  func (s *sum128) Write(data []byte) (int, error) {
   134  	for _, c := range data {
   135  		// Compute the multiplication in 4 parts to simplify carrying
   136  		s1l := (s[1] & 0xffffffff) * prime128Lower
   137  		s1h := (s[1] >> 32) * prime128Lower
   138  		s0l := (s[0]&0xffffffff)*prime128Lower + (s[1]&0xffffffff)<<prime128Shift
   139  		s0h := (s[0]>>32)*prime128Lower + (s[1]>>32)<<prime128Shift
   140  		// Carries
   141  		s1h += s1l >> 32
   142  		s0l += s1h >> 32
   143  		s0h += s0l >> 32
   144  		// Update the values
   145  		s[1] = (s1l & 0xffffffff) + (s1h << 32)
   146  		s[0] = (s0l & 0xffffffff) + (s0h << 32)
   147  		s[1] ^= uint64(c)
   148  	}
   149  	return len(data), nil
   150  }
   151  
   152  func (s *sum128a) Write(data []byte) (int, error) {
   153  	for _, c := range data {
   154  		s[1] ^= uint64(c)
   155  		// Compute the multiplication in 4 parts to simplify carrying
   156  		s1l := (s[1] & 0xffffffff) * prime128Lower
   157  		s1h := (s[1] >> 32) * prime128Lower
   158  		s0l := (s[0]&0xffffffff)*prime128Lower + (s[1]&0xffffffff)<<prime128Shift
   159  		s0h := (s[0]>>32)*prime128Lower + (s[1]>>32)<<prime128Shift
   160  		// Carries
   161  		s1h += s1l >> 32
   162  		s0l += s1h >> 32
   163  		s0h += s0l >> 32
   164  		// Update the values
   165  		s[1] = (s1l & 0xffffffff) + (s1h << 32)
   166  		s[0] = (s0l & 0xffffffff) + (s0h << 32)
   167  	}
   168  	return len(data), nil
   169  }
   170  
   171  func (s *sum32) Size() int   { return 4 }
   172  func (s *sum32a) Size() int  { return 4 }
   173  func (s *sum64) Size() int   { return 8 }
   174  func (s *sum64a) Size() int  { return 8 }
   175  func (s *sum128) Size() int  { return 16 }
   176  func (s *sum128a) Size() int { return 16 }
   177  
   178  func (s *sum32) BlockSize() int   { return 1 }
   179  func (s *sum32a) BlockSize() int  { return 1 }
   180  func (s *sum64) BlockSize() int   { return 1 }
   181  func (s *sum64a) BlockSize() int  { return 1 }
   182  func (s *sum128) BlockSize() int  { return 1 }
   183  func (s *sum128a) BlockSize() int { return 1 }
   184  
   185  func (s *sum32) Sum(in []byte) []byte {
   186  	v := uint32(*s)
   187  	return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
   188  }
   189  
   190  func (s *sum32a) Sum(in []byte) []byte {
   191  	v := uint32(*s)
   192  	return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
   193  }
   194  
   195  func (s *sum64) Sum(in []byte) []byte {
   196  	v := uint64(*s)
   197  	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))
   198  }
   199  
   200  func (s *sum64a) Sum(in []byte) []byte {
   201  	v := uint64(*s)
   202  	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))
   203  }
   204  
   205  func (s *sum128) Sum(in []byte) []byte {
   206  	return append(in,
   207  		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]),
   208  		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]),
   209  	)
   210  }
   211  
   212  func (s *sum128a) Sum(in []byte) []byte {
   213  	return append(in,
   214  		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]),
   215  		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]),
   216  	)
   217  }