package  fnv 
 
import  ( 
	"errors"  
	"hash"  
	"internal/byteorder"  
	"math/bits"  
) 
 
type  ( 
	sum32    uint32  
	sum32a   uint32  
	sum64    uint64  
	sum64a   uint64  
	sum128   [2 ]uint64  
	sum128a  [2 ]uint64  
) 
 
const  ( 
	offset32         = 2166136261  
	offset64         = 14695981039346656037  
	offset128Lower   = 0x62b821756295c58d  
	offset128Higher  = 0x6c62272e07bb0142  
	prime32          = 16777619  
	prime64          = 1099511628211  
	prime128Lower    = 0x13b  
	prime128Shift    = 24  
) 
 
 
 
func  New32  () hash .Hash32  { 
	var  s  sum32  = offset32  
	return  &s  
} 
 
 
 
func  New32a  () hash .Hash32  { 
	var  s  sum32a  = offset32  
	return  &s  
} 
 
 
 
func  New64  () hash .Hash64  { 
	var  s  sum64  = offset64  
	return  &s  
} 
 
 
 
func  New64a  () hash .Hash64  { 
	var  s  sum64a  = offset64  
	return  &s  
} 
 
 
 
func  New128  () hash .Hash  { 
	var  s  sum128  
	s [0 ] = offset128Higher  
	s [1 ] = offset128Lower  
	return  &s  
} 
 
 
 
func  New128a  () hash .Hash  { 
	var  s  sum128a  
	s [0 ] = offset128Higher  
	s [1 ] = offset128Lower  
	return  &s  
} 
 
func  (s  *sum32 ) Reset  ()   { *s  = offset32  } 
func  (s  *sum32a ) Reset  ()  { *s  = offset32  } 
func  (s  *sum64 ) Reset  ()   { *s  = offset64  } 
func  (s  *sum64a ) Reset  ()  { *s  = offset64  } 
func  (s  *sum128 ) Reset  ()  { s [0 ] = offset128Higher ; s [1 ] = offset128Lower  } 
func  (s  *sum128a ) Reset  () { s [0 ] = offset128Higher ; s [1 ] = offset128Lower  } 
 
func  (s  *sum32 ) Sum32  () uint32   { return  uint32 (*s ) } 
func  (s  *sum32a ) Sum32  () uint32  { return  uint32 (*s ) } 
func  (s  *sum64 ) Sum64  () uint64   { return  uint64 (*s ) } 
func  (s  *sum64a ) Sum64  () uint64  { return  uint64 (*s ) } 
 
func  (s  *sum32 ) Write  (data  []byte ) (int , error ) { 
	hash  := *s  
	for  _ , c  := range  data  { 
		hash  *= prime32  
		hash  ^= sum32 (c ) 
	} 
	*s  = hash  
	return  len (data ), nil  
} 
 
func  (s  *sum32a ) Write  (data  []byte ) (int , error ) { 
	hash  := *s  
	for  _ , c  := range  data  { 
		hash  ^= sum32a (c ) 
		hash  *= prime32  
	} 
	*s  = hash  
	return  len (data ), nil  
} 
 
func  (s  *sum64 ) Write  (data  []byte ) (int , error ) { 
	hash  := *s  
	for  _ , c  := range  data  { 
		hash  *= prime64  
		hash  ^= sum64 (c ) 
	} 
	*s  = hash  
	return  len (data ), nil  
} 
 
func  (s  *sum64a ) Write  (data  []byte ) (int , error ) { 
	hash  := *s  
	for  _ , c  := range  data  { 
		hash  ^= sum64a (c ) 
		hash  *= prime64  
	} 
	*s  = hash  
	return  len (data ), nil  
} 
 
func  (s  *sum128 ) Write  (data  []byte ) (int , error ) { 
	for  _ , c  := range  data  { 
		 
		s0 , s1  := bits .Mul64 (prime128Lower , s [1 ]) 
		s0  += s [1 ]<<prime128Shift  + prime128Lower *s [0 ] 
		 
		s [1 ] = s1  
		s [0 ] = s0  
		s [1 ] ^= uint64 (c ) 
	} 
	return  len (data ), nil  
} 
 
func  (s  *sum128a ) Write  (data  []byte ) (int , error ) { 
	for  _ , c  := range  data  { 
		s [1 ] ^= uint64 (c ) 
		 
		s0 , s1  := bits .Mul64 (prime128Lower , s [1 ]) 
		s0  += s [1 ]<<prime128Shift  + prime128Lower *s [0 ] 
		 
		s [1 ] = s1  
		s [0 ] = s0  
	} 
	return  len (data ), nil  
} 
 
func  (s  *sum32 ) Size  () int    { return  4  } 
func  (s  *sum32a ) Size  () int   { return  4  } 
func  (s  *sum64 ) Size  () int    { return  8  } 
func  (s  *sum64a ) Size  () int   { return  8  } 
func  (s  *sum128 ) Size  () int   { return  16  } 
func  (s  *sum128a ) Size  () int  { return  16  } 
 
func  (s  *sum32 ) BlockSize  () int    { return  1  } 
func  (s  *sum32a ) BlockSize  () int   { return  1  } 
func  (s  *sum64 ) BlockSize  () int    { return  1  } 
func  (s  *sum64a ) BlockSize  () int   { return  1  } 
func  (s  *sum128 ) BlockSize  () int   { return  1  } 
func  (s  *sum128a ) BlockSize  () int  { return  1  } 
 
func  (s  *sum32 ) Sum  (in  []byte ) []byte  { 
	v  := uint32 (*s ) 
	return  byteorder .BEAppendUint32 (in , v ) 
} 
 
func  (s  *sum32a ) Sum  (in  []byte ) []byte  { 
	v  := uint32 (*s ) 
	return  byteorder .BEAppendUint32 (in , v ) 
} 
 
func  (s  *sum64 ) Sum  (in  []byte ) []byte  { 
	v  := uint64 (*s ) 
	return  byteorder .BEAppendUint64 (in , v ) 
} 
 
func  (s  *sum64a ) Sum  (in  []byte ) []byte  { 
	v  := uint64 (*s ) 
	return  byteorder .BEAppendUint64 (in , v ) 
} 
 
func  (s  *sum128 ) Sum  (in  []byte ) []byte  { 
	ret  := byteorder .BEAppendUint64 (in , s [0 ]) 
	return  byteorder .BEAppendUint64 (ret , s [1 ]) 
} 
 
func  (s  *sum128a ) Sum  (in  []byte ) []byte  { 
	ret  := byteorder .BEAppendUint64 (in , s [0 ]) 
	return  byteorder .BEAppendUint64 (ret , s [1 ]) 
} 
 
const  ( 
	magic32           = "fnv\x01"  
	magic32a          = "fnv\x02"  
	magic64           = "fnv\x03"  
	magic64a          = "fnv\x04"  
	magic128          = "fnv\x05"  
	magic128a         = "fnv\x06"  
	marshaledSize32   = len (magic32 ) + 4  
	marshaledSize64   = len (magic64 ) + 8  
	marshaledSize128  = len (magic128 ) + 8 *2  
) 
 
func  (s  *sum32 ) AppendBinary  (b  []byte ) ([]byte , error ) { 
	b  = append (b , magic32 ...) 
	b  = byteorder .BEAppendUint32 (b , uint32 (*s )) 
	return  b , nil  
} 
 
func  (s  *sum32 ) MarshalBinary  () ([]byte , error ) { 
	return  s .AppendBinary (make ([]byte , 0 , marshaledSize32 )) 
} 
 
func  (s  *sum32a ) AppendBinary  (b  []byte ) ([]byte , error ) { 
	b  = append (b , magic32a ...) 
	b  = byteorder .BEAppendUint32 (b , uint32 (*s )) 
	return  b , nil  
} 
 
func  (s  *sum32a ) MarshalBinary  () ([]byte , error ) { 
	return  s .AppendBinary (make ([]byte , 0 , marshaledSize32 )) 
} 
 
func  (s  *sum64 ) AppendBinary  (b  []byte ) ([]byte , error ) { 
	b  = append (b , magic64 ...) 
	b  = byteorder .BEAppendUint64 (b , uint64 (*s )) 
	return  b , nil  
} 
 
func  (s  *sum64 ) MarshalBinary  () ([]byte , error ) { 
	return  s .AppendBinary (make ([]byte , 0 , marshaledSize64 )) 
} 
 
func  (s  *sum64a ) AppendBinary  (b  []byte ) ([]byte , error ) { 
	b  = append (b , magic64a ...) 
	b  = byteorder .BEAppendUint64 (b , uint64 (*s )) 
	return  b , nil  
} 
 
func  (s  *sum64a ) MarshalBinary  () ([]byte , error ) { 
	return  s .AppendBinary (make ([]byte , 0 , marshaledSize64 )) 
} 
 
func  (s  *sum128 ) AppendBinary  (b  []byte ) ([]byte , error ) { 
	b  = append (b , magic128 ...) 
	b  = byteorder .BEAppendUint64 (b , s [0 ]) 
	b  = byteorder .BEAppendUint64 (b , s [1 ]) 
	return  b , nil  
} 
 
func  (s  *sum128 ) MarshalBinary  () ([]byte , error ) { 
	return  s .AppendBinary (make ([]byte , 0 , marshaledSize128 )) 
} 
 
func  (s  *sum128a ) AppendBinary  (b  []byte ) ([]byte , error ) { 
	b  = append (b , magic128a ...) 
	b  = byteorder .BEAppendUint64 (b , s [0 ]) 
	b  = byteorder .BEAppendUint64 (b , s [1 ]) 
	return  b , nil  
} 
 
func  (s  *sum128a ) MarshalBinary  () ([]byte , error ) { 
	return  s .AppendBinary (make ([]byte , 0 , marshaledSize128 )) 
} 
 
func  (s  *sum32 ) UnmarshalBinary  (b  []byte ) error  { 
	if  len (b ) < len (magic32 ) || string (b [:len (magic32 )]) != magic32  { 
		return  errors .New ("hash/fnv: invalid hash state identifier" ) 
	} 
	if  len (b ) != marshaledSize32  { 
		return  errors .New ("hash/fnv: invalid hash state size" ) 
	} 
	*s  = sum32 (byteorder .BEUint32 (b [4 :])) 
	return  nil  
} 
 
func  (s  *sum32a ) UnmarshalBinary  (b  []byte ) error  { 
	if  len (b ) < len (magic32a ) || string (b [:len (magic32a )]) != magic32a  { 
		return  errors .New ("hash/fnv: invalid hash state identifier" ) 
	} 
	if  len (b ) != marshaledSize32  { 
		return  errors .New ("hash/fnv: invalid hash state size" ) 
	} 
	*s  = sum32a (byteorder .BEUint32 (b [4 :])) 
	return  nil  
} 
 
func  (s  *sum64 ) UnmarshalBinary  (b  []byte ) error  { 
	if  len (b ) < len (magic64 ) || string (b [:len (magic64 )]) != magic64  { 
		return  errors .New ("hash/fnv: invalid hash state identifier" ) 
	} 
	if  len (b ) != marshaledSize64  { 
		return  errors .New ("hash/fnv: invalid hash state size" ) 
	} 
	*s  = sum64 (byteorder .BEUint64 (b [4 :])) 
	return  nil  
} 
 
func  (s  *sum64a ) UnmarshalBinary  (b  []byte ) error  { 
	if  len (b ) < len (magic64a ) || string (b [:len (magic64a )]) != magic64a  { 
		return  errors .New ("hash/fnv: invalid hash state identifier" ) 
	} 
	if  len (b ) != marshaledSize64  { 
		return  errors .New ("hash/fnv: invalid hash state size" ) 
	} 
	*s  = sum64a (byteorder .BEUint64 (b [4 :])) 
	return  nil  
} 
 
func  (s  *sum128 ) UnmarshalBinary  (b  []byte ) error  { 
	if  len (b ) < len (magic128 ) || string (b [:len (magic128 )]) != magic128  { 
		return  errors .New ("hash/fnv: invalid hash state identifier" ) 
	} 
	if  len (b ) != marshaledSize128  { 
		return  errors .New ("hash/fnv: invalid hash state size" ) 
	} 
	s [0 ] = byteorder .BEUint64 (b [4 :]) 
	s [1 ] = byteorder .BEUint64 (b [12 :]) 
	return  nil  
} 
 
func  (s  *sum128a ) UnmarshalBinary  (b  []byte ) error  { 
	if  len (b ) < len (magic128a ) || string (b [:len (magic128a )]) != magic128a  { 
		return  errors .New ("hash/fnv: invalid hash state identifier" ) 
	} 
	if  len (b ) != marshaledSize128  { 
		return  errors .New ("hash/fnv: invalid hash state size" ) 
	} 
	s [0 ] = byteorder .BEUint64 (b [4 :]) 
	s [1 ] = byteorder .BEUint64 (b [12 :]) 
	return  nil  
}