ソースを参照

updated mishmash - added second hash capabilities by converting Mishmash to a modified variadic function - takes and uses the accumulator if given

master
William Dillon 3年前
コミット
7bad662b17
3個のファイルの変更48行の追加18行の削除
  1. 8
    0
      README.md
  2. 26
    11
      mishmash.go
  3. 14
    7
      mishmash_test.go

+ 8
- 0
README.md ファイルの表示

@@ -0,0 +1,8 @@
# Mishmash

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.

+ 26
- 11
mishmash.go ファイルの表示

@@ -1,9 +1,3 @@
// 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

var primes = [256]uint32{2781111551, 4115761697, 2188512439, 3902941499, 4078728127, 2919449173, 3950407729, 4081733563,
@@ -44,8 +38,9 @@ func slct(n uint64) uint32 {
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++ {
b := buffer[i]
accumulator += uint64(slct(accumulator)) + uint64(b)
@@ -56,7 +51,27 @@ func engine(buffer []byte, length int) uint64 {
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))
}
*/

+ 14
- 7
mishmash_test.go ファイルの表示

@@ -5,19 +5,26 @@ import (
"testing"
)

func TestMishmashString(t *testing.T) {
func TestMishmash(t *testing.T) {
want := "9d923077"
if got := fmt.Sprintf("%08x", Mishmash([]byte("google.com"))); want != got {
hash, _ := Mishmash([]byte("google.com"))
got := fmt.Sprintf("%08x", hash)
if want != got {
t.Error("Parse() = got", got, "want", want)
} else {
fmt.Println("TestMishmashString passed")
fmt.Println("TestMishmash Passed")
}
}
func TestMishmashUint32(t *testing.T) {
var want uint32 = 2643603575
if got := Mishmash([]byte("google.com")); want != got {

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 {
t.Error("Parse() = got", got, "want", want)
} else {
fmt.Println("TestMishmashUint32 passed")
fmt.Println("TestSecondHash Passed")
}

}

読み込み中…
キャンセル
保存