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 ) MarshalBinary () ([]byte , error ) {
b := make ([]byte , 0 , marshaledSize32 )
b = append (b , magic32 ...)
b = byteorder .BeAppendUint32 (b , uint32 (*s ))
return b , nil
}
func (s *sum32a ) MarshalBinary () ([]byte , error ) {
b := make ([]byte , 0 , marshaledSize32 )
b = append (b , magic32a ...)
b = byteorder .BeAppendUint32 (b , uint32 (*s ))
return b , nil
}
func (s *sum64 ) MarshalBinary () ([]byte , error ) {
b := make ([]byte , 0 , marshaledSize64 )
b = append (b , magic64 ...)
b = byteorder .BeAppendUint64 (b , uint64 (*s ))
return b , nil
}
func (s *sum64a ) MarshalBinary () ([]byte , error ) {
b := make ([]byte , 0 , marshaledSize64 )
b = append (b , magic64a ...)
b = byteorder .BeAppendUint64 (b , uint64 (*s ))
return b , nil
}
func (s *sum128 ) MarshalBinary () ([]byte , error ) {
b := make ([]byte , 0 , marshaledSize128 )
b = append (b , magic128 ...)
b = byteorder .BeAppendUint64 (b , s [0 ])
b = byteorder .BeAppendUint64 (b , s [1 ])
return b , nil
}
func (s *sum128a ) MarshalBinary () ([]byte , error ) {
b := make ([]byte , 0 , marshaledSize128 )
b = append (b , magic128a ...)
b = byteorder .BeAppendUint64 (b , s [0 ])
b = byteorder .BeAppendUint64 (b , s [1 ])
return b , nil
}
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
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .