diff --git a/murmur128.go b/murmur128.go index a4fd7e7..9f849bd 100644 --- a/murmur128.go +++ b/murmur128.go @@ -2,9 +2,9 @@ package murmur3 import ( //"encoding/binary" + "encoding/binary" "hash" "math/bits" - "unsafe" ) const ( @@ -65,8 +65,8 @@ func (d *digest128) bmix(p []byte) (tail []byte) { nblocks := len(p) / 16 for i := 0; i < nblocks; i++ { - t := (*[2]uint64)(unsafe.Pointer(&p[i*16])) - k1, k2 := t[0], t[1] + k1 := binary.LittleEndian.Uint64(p[i*16:]) + k2 := binary.LittleEndian.Uint64(p[i*16+8:]) k1 *= c1_128 k1 = bits.RotateLeft64(k1, 31) diff --git a/murmur32.go b/murmur32.go index 552976a..7adbada 100644 --- a/murmur32.go +++ b/murmur32.go @@ -3,9 +3,9 @@ package murmur3 // http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/hash/Murmur3_32HashFunction.java import ( + "encoding/binary" "hash" "math/bits" - "unsafe" ) // Make sure interfaces are correctly implemented. @@ -53,7 +53,7 @@ func (d *digest32) bmix(p []byte) (tail []byte) { nblocks := len(p) / 4 for i := 0; i < nblocks; i++ { - k1 := *(*uint32)(unsafe.Pointer(&p[i*4])) + k1 := binary.LittleEndian.Uint32(p[i*4:]) k1 *= c1_32 k1 = bits.RotateLeft32(k1, 15) @@ -115,13 +115,8 @@ func Sum32WithSeed(data []byte, seed uint32) uint32 { h1 := seed nblocks := len(data) / 4 - var p uintptr - if len(data) > 0 { - p = uintptr(unsafe.Pointer(&data[0])) - } - p1 := p + uintptr(4*nblocks) - for ; p < p1; p += 4 { - k1 := *(*uint32)(unsafe.Pointer(p)) + for i := 0; i < nblocks; i++ { + k1 := binary.LittleEndian.Uint32(data[i*4:]) k1 *= c1_32 k1 = bits.RotateLeft32(k1, 15) diff --git a/murmur_test.go b/murmur_test.go index 945e4e2..dd2d798 100644 --- a/murmur_test.go +++ b/murmur_test.go @@ -187,3 +187,14 @@ func Benchmark128(b *testing.B) { }) } } + +func TestUnalignedWrite(t *testing.T) { + // Causes "fatal error: checkptr: unsafe pointer conversion" for unsafe + // pointer conversions in Go 1.14+ + b := make([]byte, 128) + for i := 0; i < 16; i++ { + Sum32(b[i:]) + Sum64(b[i:]) + Sum128(b[i:]) + } +}