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 }