Pārlūkot izejas kodu

updated mishmash - engine returns accumulator for use with Mishmash which takes it as an optional seed. Mishmash can be seeded however desired through this mechanism as well. Added simple function to decode accumulator for ease of use when we're going to be double hashing

master
William Dillon pirms 3 gadiem
vecāks
revīzija
ba60fcb929
3 mainītis faili ar 46 papildinājumiem un 21 dzēšanām
  1. 1
    1
      README.md
  2. 22
    12
      mishmash.go
  3. 23
    8
      mishmash_test.go

+ 1
- 1
README.md Parādīt failu

@@ -5,4 +5,4 @@ this is a non-cryptographic hash optimized for short strings.
adapted from CodeDweller/mishmash.h/cpp
https://code.microneil.com/madscientist/CodeDweller/src/branch/master

to use: use the Mishmash function. If you're in need of a second hash (or could be) keep the second value returned, that's the accumulator. Mishmash will take that in a second call, along with your string, to create a second hash.
to use: use the Mishmash function. If you're in need of a second hash use Engine instead, which will return the accumulator. You can use the MishmashAccumulator function to mishmash your accumulator, and could also feed that accumulator back into Mishmash to double hash.

+ 22
- 12
mishmash.go Parādīt failu

@@ -39,39 +39,49 @@ func slct(n uint64) uint32 {
}

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++ {
b := buffer[i]
accumulator += uint64(slct(accumulator)) + uint64(b)
accumulator *= uint64(slct(uint64(b)))
accumulator += accumulator >> 32

}
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
if 0 == len(nums) {
// seeding with 0 by default - could be changed
accumulator = Engine(buffer, len(buffer), 0)
} else {
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"
// and then collecting the hash and accumulator. Given
// and then collecting the hash. Given
// 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() {
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)
}
*/

+ 23
- 8
mishmash_test.go Parādīt failu

@@ -7,9 +7,7 @@ import (

func TestMishmash(t *testing.T) {
want := "9d923077"
hash, _ := Mishmash([]byte("google.com"))
got := fmt.Sprintf("%08x", hash)
if want != got {
if got := fmt.Sprintf("%08x", Mishmash([]byte("google.com"))); want != got {
t.Error("Parse() = got", got, "want", want)
} else {
fmt.Println("TestMishmash Passed")
@@ -17,14 +15,31 @@ func TestMishmash(t *testing.T) {
}

func TestSecondHash(t *testing.T) {
want := "65df1304"
_, accum := Mishmash([]byte("google.com"))
hash, accum := Mishmash([]byte("google.com"), accum)
got := fmt.Sprintf("%08x", hash)
if want != got {
want := "3fbdb348"
hash := Mishmash([]byte("google.com"))
if got := fmt.Sprintf("%08x", Mishmash([]byte("google.com"), uint64(hash))); want != got {
t.Error("Parse() = got", got, "want", want)
} else {
fmt.Println("TestSecondHash Passed")
}
}

func TestSeedOne(t *testing.T) {
want := "cebf5691"
if got := fmt.Sprintf("%08x", Mishmash([]byte("google.com"), uint64(1))); want != got {
t.Error("Parse() = got", got, "want", want)
} else {
fmt.Println("TestSeedOne Passed")
}
}

func TestEngineAndAccumulator(t *testing.T) {
want := "65df1304"
test := []byte("google.com")
accum := Engine(test, len(test), 0)
if got := fmt.Sprintf("%08x", Mishmash(test, accum)); want != got {
t.Error("Parse() = got", got, "want", want)
} else {
fmt.Println("TestEngineAndAccumulator Passed")
}
}

Notiek ielāde…
Atcelt
Saglabāt