64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
|
|
package mishmash
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bufio"
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"strconv"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
const The32BitHashesFilename = "cppmishmash32.txt"
|
||
|
|
|
||
|
|
type WordWithHashString struct {
|
||
|
|
word, hash string
|
||
|
|
}
|
||
|
|
|
||
|
|
func ParseHashesFile(filename string) ([]WordWithHashString, error) {
|
||
|
|
f, err := os.Open(filename)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("error opening %s: %w", filename, err)
|
||
|
|
}
|
||
|
|
defer f.Close()
|
||
|
|
scanner := bufio.NewScanner(f)
|
||
|
|
results := make([]WordWithHashString, 0)
|
||
|
|
lineNumber := 0
|
||
|
|
for scanner.Scan() {
|
||
|
|
lineNumber++
|
||
|
|
line := strings.TrimSpace(scanner.Text())
|
||
|
|
if len(line) == 0 {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
fields := strings.Fields(line)
|
||
|
|
if len(fields) != 2 {
|
||
|
|
return nil, fmt.Errorf("error: malformed line %s at line %d", line, lineNumber)
|
||
|
|
}
|
||
|
|
results = append(results, WordWithHashString{fields[0], fields[1]})
|
||
|
|
}
|
||
|
|
return results, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestAgainstCppMishmash32(t *testing.T) {
|
||
|
|
wordsWithHashes, err := ParseHashesFile(The32BitHashesFilename)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("error: %v\n", err)
|
||
|
|
}
|
||
|
|
start := time.Now()
|
||
|
|
for _, obj := range wordsWithHashes {
|
||
|
|
word, hashString := obj.word, obj.hash
|
||
|
|
want, err := strconv.ParseUint(hashString, 16, 32)
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("error parsing %+v: %v\n", obj, err)
|
||
|
|
}
|
||
|
|
hasher := Mishmash32{}
|
||
|
|
hasher.Write([]byte(word))
|
||
|
|
got := hasher.Sum32()
|
||
|
|
if uint32(want) != got {
|
||
|
|
t.Fatalf("error for %q: wanted %08x; got %08x\n", word, want, got)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
fmt.Printf("finished testing %d words after %s\n", len(wordsWithHashes), time.Since(start))
|
||
|
|
}
|