|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func Engine(buffer []byte, length int, accumulator uint64) uint64 { |
|
|
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) |
|
|
accumulator *= uint64(slct(uint64(b))) |
|
|
accumulator *= uint64(slct(uint64(b))) |
|
|
accumulator += accumulator >> 32 |
|
|
accumulator += accumulator >> 32 |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
return accumulator |
|
|
return accumulator |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func Mishmash(buffer []byte, nums ...uint64) (uint32, uint64) { |
|
|
|
|
|
// returns mishmashHash, accumulator |
|
|
|
|
|
|
|
|
func Mishmash(buffer []byte, nums ...uint64) uint32 { |
|
|
|
|
|
// nums is a seed/accumulator |
|
|
var accumulator uint64 |
|
|
var accumulator uint64 |
|
|
if 0 == len(nums) { |
|
|
if 0 == len(nums) { |
|
|
|
|
|
// seeding with 0 by default - could be changed |
|
|
accumulator = Engine(buffer, len(buffer), 0) |
|
|
accumulator = Engine(buffer, len(buffer), 0) |
|
|
} else { |
|
|
} else { |
|
|
accumulator = Engine(buffer, len(buffer), nums[0]) |
|
|
accumulator = Engine(buffer, len(buffer), nums[0]) |
|
|
} |
|
|
} |
|
|
return uint32(accumulator & 0x00000000ffffffff), accumulator |
|
|
|
|
|
|
|
|
return uint32(accumulator & 0x00000000ffffffff) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func MishmashAccumulator(accumulator uint64) uint32 { |
|
|
|
|
|
// use when collecting accumulators for second hash |
|
|
|
|
|
return uint32(accumulator & 0x00000000ffffffff) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// example below shows calling Mishmash on "hello world" |
|
|
// example below shows calling Mishmash on "hello world" |
|
|
// and then collecting the hash and accumulator. Given |
|
|
|
|
|
|
|
|
// and then collecting the hash. Given |
|
|
// a collision we simply call Mishmash again, giving it |
|
|
// a collision we simply call Mishmash again, giving it |
|
|
// the accumulator this time, and get a second hash. |
|
|
|
|
|
|
|
|
// the first hash as a seed this time and get a second hash. |
|
|
/* |
|
|
/* |
|
|
func main() { |
|
|
func main() { |
|
|
buf := []byte("Hello world") |
|
|
buf := []byte("Hello world") |
|
|
hash, accumulator := Mishmash(buf) |
|
|
|
|
|
fmt.Println(uint32(hash & 0x00000000ffffffff)) |
|
|
|
|
|
secondHash, accumulator := Mishmash(buf, accumulator) |
|
|
|
|
|
fmt.Println(uint32(secondHash & 0x00000000ffffffff)) |
|
|
|
|
|
|
|
|
// grab the accumulator if necessary |
|
|
|
|
|
accum := Engine(buf, len(buf), 0) |
|
|
|
|
|
// grab the hash - decode accumulator into hash |
|
|
|
|
|
hash := MishmashAccumulator(accum) |
|
|
|
|
|
fmt.Printf("%08x\n", hash) |
|
|
|
|
|
// now get second hash - seed with accumulator |
|
|
|
|
|
secondHash := Mishmash(buf, accum) |
|
|
|
|
|
fmt.Printf("%08x\n", secondHash) |
|
|
|
|
|
// you can also get a simple hash |
|
|
|
|
|
simpleMishmash := Mishmash(buf) |
|
|
|
|
|
fmt.Printf("%08x\n", simpleMishmash) |
|
|
} |
|
|
} |
|
|
*/ |
|
|
*/ |