github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/bloom/murmurhash3.go (about)

     1  // Copyright (c) 2013, 2014 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package bloom
     6  
     7  import (
     8  	"encoding/binary"
     9  )
    10  
    11  // The following constants are used by the MurmurHash3 algorithm.
    12  const (
    13  	murmurC1 = 0xcc9e2d51
    14  	murmurC2 = 0x1b873593
    15  	murmurR1 = 15
    16  	murmurR2 = 13
    17  	murmurM  = 5
    18  	murmurN  = 0xe6546b64
    19  )
    20  
    21  // MurmurHash3 implements a non-cryptographic hash function using the
    22  // MurmurHash3 algorithm.  This implementation yields a 32-bit hash value which
    23  // is suitable for general hash-based lookups.  The seed can be used to
    24  // effectively randomize the hash function.  This makes it ideal for use in
    25  // bloom filters which need multiple independent hash functions.
    26  func MurmurHash3(seed uint32, data []byte) uint32 {
    27  	dataLen := uint32(len(data))
    28  	hash := seed
    29  	var k uint32
    30  	numBlocks := dataLen / 4
    31  
    32  	// Calculate the hash in 4-byte chunks.
    33  	for i := uint32(0); i < numBlocks; i++ {
    34  		k = binary.LittleEndian.Uint32(data[i*4:])
    35  		k *= murmurC1
    36  		k = (k << murmurR1) | (k >> (32 - murmurR1))
    37  		k *= murmurC2
    38  
    39  		hash ^= k
    40  		hash = (hash << murmurR2) | (hash >> (32 - murmurR2))
    41  		hash = hash*murmurM + murmurN
    42  	}
    43  
    44  	// Handle remaining bytes.
    45  	tailIdx := numBlocks * 4
    46  	k = 0
    47  
    48  	switch dataLen & 3 {
    49  	case 3:
    50  		k ^= uint32(data[tailIdx+2]) << 16
    51  		fallthrough
    52  	case 2:
    53  		k ^= uint32(data[tailIdx+1]) << 8
    54  		fallthrough
    55  	case 1:
    56  		k ^= uint32(data[tailIdx])
    57  		k *= murmurC1
    58  		k = (k << murmurR1) | (k >> (32 - murmurR1))
    59  		k *= murmurC2
    60  		hash ^= k
    61  	}
    62  
    63  	// Finalization.
    64  	hash ^= uint32(dataLen)
    65  	hash ^= hash >> 16
    66  	hash *= 0x85ebca6b
    67  	hash ^= hash >> 13
    68  	hash *= 0xc2b2ae35
    69  	hash ^= hash >> 16
    70  
    71  	return hash
    72  }