Home | History | Annotate | Download | only in fnv
      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