|
|
|
|
|
|
|
|
// mishmash.go |
|
|
|
|
|
// Copyright (C) 2021 MicroNeil Research Corporation. |
|
|
|
|
|
// |
|
|
|
|
|
// This software is released under the MIT license. See LICENSE.TXT. |
|
|
|
|
|
// |
|
|
|
|
|
// Mishamash is a non-cryptographic hash optimized for short strings. |
|
|
|
|
|
package mishmash |
|
|
package mishmash |
|
|
|
|
|
|
|
|
var primes = [256]uint32{2781111551, 4115761697, 2188512439, 3902941499, 4078728127, 2919449173, 3950407729, 4081733563, |
|
|
var primes = [256]uint32{2781111551, 4115761697, 2188512439, 3902941499, 4078728127, 2919449173, 3950407729, 4081733563, |
|
|
|
|
|
|
|
|
return primes[n&0xff] |
|
|
return primes[n&0xff] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func engine(buffer []byte, length int) uint64 { |
|
|
|
|
|
var accumulator uint64 = 0 |
|
|
|
|
|
|
|
|
func Engine(buffer []byte, length int, accumulator uint64) uint64 { |
|
|
|
|
|
// exported for ease of use - Mishmash below returns |
|
|
|
|
|
// both the mishmash AND accumulator |
|
|
for i := 0; i < length; i++ { |
|
|
for i := 0; i < length; i++ { |
|
|
b := buffer[i] |
|
|
b := buffer[i] |
|
|
accumulator += uint64(slct(accumulator)) + uint64(b) |
|
|
accumulator += uint64(slct(accumulator)) + uint64(b) |
|
|
|
|
|
|
|
|
return accumulator |
|
|
return accumulator |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func Mishmash(buffer []byte) uint32 { |
|
|
|
|
|
accumulator := engine(buffer, len(buffer)) |
|
|
|
|
|
return uint32(accumulator & 0x00000000ffffffff) |
|
|
|
|
|
|
|
|
func Mishmash(buffer []byte, nums ...uint64) (uint32, uint64) { |
|
|
|
|
|
// returns mishmashHash, accumulator |
|
|
|
|
|
var accumulator uint64 |
|
|
|
|
|
if 0 == len(nums) { |
|
|
|
|
|
accumulator = Engine(buffer, len(buffer), 0) |
|
|
|
|
|
} else { |
|
|
|
|
|
accumulator = Engine(buffer, len(buffer), nums[0]) |
|
|
|
|
|
} |
|
|
|
|
|
return uint32(accumulator & 0x00000000ffffffff), accumulator |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// example below shows calling Mishmash on "hello world" |
|
|
|
|
|
// and then collecting the hash and accumulator. Given |
|
|
|
|
|
// a collision we simply call Mishmash again, giving it |
|
|
|
|
|
// the accumulator this time, and get a second hash. |
|
|
|
|
|
/* |
|
|
|
|
|
func main() { |
|
|
|
|
|
buf := []byte("Hello world") |
|
|
|
|
|
hash, accumulator := Mishmash(buf) |
|
|
|
|
|
fmt.Println(uint32(hash & 0x00000000ffffffff)) |
|
|
|
|
|
secondHash, accumulator := Mishmash(buf, accumulator) |
|
|
|
|
|
fmt.Println(uint32(secondHash & 0x00000000ffffffff)) |
|
|
} |
|
|
} |
|
|
|
|
|
*/ |