func TestSmhasherSeed(t *TState) bool {
	h := newHashSet()
	const N = 100000
	s := "hello"
	for i := 0; i < N; i++ {
		h.addS_seed(s, uintptr(i))
	}
	return h.check()
}
Make sure different seed values generate different hashes.
package smhasher
import (
	"fmt"
	"leb.io/hashland/hashf"
	"math"
	"math/rand"
	"strings"
	"time"
)
func HaveGoodHash() bool {
	return true
}
func Short() bool {
	return false
}
func SetBytes(amt int64) {
}
func BytesHash(b []byte, aseed uintptr) uintptr {
	seed := uint64(aseed)
	h := hashf.Hashf(b, seed)
	return uintptr(h)
}
func StringHash(s string, aseed uintptr) uintptr {
	seed := uint64(aseed)
	b := make([]byte, len(s), len(s))
	b = b[:]
	copy(b, s)
	h := hashf.Hashf(b, seed)
	return uintptr(h)
}
func Int32Hash(i uint32, aseed uintptr) uintptr {
	seed := uint64(aseed)
	b := make([]byte, 4, 4)
	b = b[:]
	b[0], b[1], b[2], b[3] = byte(i&0xFF), byte((i>>8)&0xFF), byte((i>>16)&0xFF), byte((i>>24)&0xFF)
	h := hashf.Hashf(b, seed)
	return uintptr(h)
}
func Int64Hash(i uint64, aseed uintptr) uintptr {
	seed := uint64(aseed)
	b := make([]byte, 8, 8)
	b = b[:]
	b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7] = byte(i&0xFF), byte((i>>8)&0xFF), byte((i>>16)&0xFF), byte((i>>24)&0xFF), byte((i>>32)&0xFF), byte((i>>40)&0xFF), byte((i>>48)&0xFF),
		byte((i>>56)&0xFF)
	h := hashf.Hashf(b, seed)
	return uintptr(h)
}
func TestSmhasherSanity(t *TState) (ret bool) {
	r := rand.New(rand.NewSource(1234))
	const REP = 10
	const KEYMAX = 128
	const PAD = 16
	const OFFMAX = 16
	for k := 0; k < REP; k++ {
		for n := 0; n < KEYMAX; n++ {
			for i := 0; i < OFFMAX; i++ {
				var b [KEYMAX + OFFMAX + 2*PAD]byte
				var c [KEYMAX + OFFMAX + 2*PAD]byte
				randBytes(r, b[:])
				randBytes(r, c[:])
				copy(c[PAD+i:PAD+i+n], b[PAD:PAD+n])
				if BytesHash(b[PAD:PAD+n], 0) != BytesHash(c[PAD+i:PAD+i+n], 0) {
					fmt.Printf("hash depends on bytes outside key")
					ret = true
				}
			}
		}
	}
	return
}
type HashSet struct {
	m map[uintptr]struct{}  
	n int                   
}
func newHashSet() *HashSet {
	return &HashSet{make(map[uintptr]struct{}), 0}
}
func (s *HashSet) add(h uintptr) {
	s.m[h] = struct{}{}
	s.n++
}
func (s *HashSet) addS(x string) {
	s.add(StringHash(x, 0))
}
func (s *HashSet) addB(x []byte) {
	s.add(BytesHash(x, 0))
}
func (s *HashSet) addS_seed(x string, seed uintptr) {
	s.add(StringHash(x, seed))
}
func (s *HashSet) check() (ret bool) {
	const SLOP = 10.0
	collisions := s.n - len(s.m)
	pairs := int64(s.n) * int64(s.n-1) / 2
	expected := float64(pairs) / math.Pow(2.0, float64(hashSize))
	stddev := math.Sqrt(expected)
	if float64(collisions) > expected+SLOP*3*stddev {
		fmt.Printf("check: unexpected number of collisions: got=%d mean=%f stddev=%f\n", collisions, expected, stddev)
		ret = true
	}
	return
}
func TestSmhasherAppendedZeros(t *TState) bool {
	s := "hello" + strings.Repeat("\x00", 256)
	h := newHashSet()
	for i := 0; i <= len(s); i++ {
		h.addS(s[:i])
	}
	return h.check()
}
func TestSmhasherSmallKeys(t *TState) bool {
	h := newHashSet()
	var b [3]byte
	for i := 0; i < 256; i++ {
		b[0] = byte(i)
		h.addB(b[:1])
		for j := 0; j < 256; j++ {
			b[1] = byte(j)
			h.addB(b[:2])
			if !Short() {
				for k := 0; k < 256; k++ {
					b[2] = byte(k)
					h.addB(b[:3])
				}
			}
		}
	}
	return h.check()
}
func TestSmhasherZeros(t *TState) bool {
	N := 256 * 1024
	if Short() {
		N = 1024
	}
	h := newHashSet()
	b := make([]byte, N)
	for i := 0; i <= N; i++ {
		h.addB(b[:i])
	}
	return h.check()
}
func TestSmhasherTwoNonzero(t *TState) bool {
	if Short() {
	}
	h := newHashSet()
	for n := 2; n <= 16; n++ {
		twoNonZero(h, n)
	}
	return h.check()
}
func twoNonZero(h *HashSet, n int) {
	b := make([]byte, n)
	h.addB(b[:])
	for i := 0; i < n; i++ {
		for x := 1; x < 256; x++ {
			b[i] = byte(x)
			h.addB(b[:])
			b[i] = 0
		}
	}
	for i := 0; i < n; i++ {
		for x := 1; x < 256; x++ {
			b[i] = byte(x)
			for j := i + 1; j < n; j++ {
				for y := 1; y < 256; y++ {
					b[j] = byte(y)
					h.addB(b[:])
					b[j] = 0
				}
			}
			b[i] = 0
		}
	}
}
func TestSmhasherCyclic(t *TState) (ret bool) {
	if Short() {
	}
	if !HaveGoodHash() {
	}
	r := rand.New(rand.NewSource(1234))
	const REPEAT = 8
	const N = 1000000
	for n := 4; n <= 12; n++ {
		h := newHashSet()
		b := make([]byte, REPEAT*n)
		for i := 0; i < N; i++ {
			b[0] = byte(i * 79 % 97)
			b[1] = byte(i * 43 % 137)
			b[2] = byte(i * 151 % 197)
			b[3] = byte(i * 199 % 251)
			randBytes(r, b[4:n])
			for j := n; j < n*REPEAT; j++ {
				b[j] = b[j-n]
			}
			h.addB(b)
		}
		if h.check() {
			ret = true
		}
	}
	return
}
type pair struct {
	n int
	k int
}
var pairs = []pair{pair{32, 6}, pair{40, 6}, pair{48, 5}, pair{56, 5}, pair{64, 5}, pair{96, 4}, pair{256, 3}, pair{2048, 2}}
func TestSmhasherSparse(t *TState) (ret bool) {
	if Short() {
	}
	for _, v := range pairs {
		if sparse(v.n, v.k) {
			ret = true
		}
	}
	return
}
func sparse(n int, k int) bool {
	b := make([]byte, n/8)
	h := newHashSet()
	setbits(h, b, 0, k)
	return h.check()
}
func setbits(h *HashSet, b []byte, i int, k int) {
	h.addB(b)
	if k == 0 {
		return
	}
	for j := i; j < len(b)*8; j++ {
		b[j/8] |= byte(1 << uint(j&7))
		setbits(h, b, j+1, k-1)
		b[j/8] &= byte(^(1 << uint(j&7)))
	}
}
type Permutation struct {
	n int
	s []uint32
}
var Permutations = []Permutation{
	Permutation{8, []uint32{0, 1, 2, 3, 4, 5, 6, 7}},
	Permutation{8, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}},
	Permutation{20, []uint32{0, 1}},
	Permutation{20, []uint32{0, 1 << 31}},
	Permutation{6, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}},
}
func TestSmhasherPermutation(t *TState) bool {
	if Short() {
	}
	if !HaveGoodHash() {
	}
	for _, v := range Permutations {
		fmt.Printf("\n\t\tn=%d, s=%v", v.n, v.s)
		permutation(v.s, v.n)
	}
	return false
}
func permutation(s []uint32, n int) {
	b := make([]byte, n*4)
	h := newHashSet()
	genPerm(h, b, s, 0)
	h.check()
}
func genPerm(h *HashSet, b []byte, s []uint32, n int) {
	h.addB(b[:n])
	if n == len(b) {
		return
	}
	for _, v := range s {
		b[n] = byte(v)
		b[n+1] = byte(v >> 8)
		b[n+2] = byte(v >> 16)
		b[n+3] = byte(v >> 24)
		genPerm(h, b, s, n+4)
	}
}
type Key interface {
	clear()               
	random(r *rand.Rand)  
	bits() int            
	flipBit(i int)        
	hash() uintptr        
	name() string         
}
type BytesKey struct {
	b []byte
}
func (k *BytesKey) clear() {
	for i := range k.b {
		k.b[i] = 0
	}
}
func (k *BytesKey) random(r *rand.Rand) {
	randBytes(r, k.b)
}
func (k *BytesKey) bits() int {
	return len(k.b) * 8
}
func (k *BytesKey) flipBit(i int) {
	k.b[i>>3] ^= byte(1 << uint(i&7))
}
func (k *BytesKey) hash() uintptr {
	return BytesHash(k.b, 0)
}
func (k *BytesKey) name() string {
	return fmt.Sprintf("bytes%d", len(k.b))
}
type Int32Key struct {
	i uint32
}
func (k *Int32Key) clear() {
	k.i = 0
}
func (k *Int32Key) random(r *rand.Rand) {
	k.i = r.Uint32()
}
func (k *Int32Key) bits() int {
	return 32
}
func (k *Int32Key) flipBit(i int) {
	k.i ^= 1 << uint(i)
}
func (k *Int32Key) hash() uintptr {
	return Int32Hash(k.i, 0)
}
func (k *Int32Key) name() string {
	return "int32"
}
type Int64Key struct {
	i uint64
}
func (k *Int64Key) clear() {
	k.i = 0
}
func (k *Int64Key) random(r *rand.Rand) {
	k.i = uint64(r.Uint32()) + uint64(r.Uint32())<<32
}
func (k *Int64Key) bits() int {
	return 64
}
func (k *Int64Key) flipBit(i int) {
	k.i ^= 1 << uint(i)
}
func (k *Int64Key) hash() uintptr {
	return Int64Hash(k.i, 0)
}
func (k *Int64Key) name() string {
	return "int64"
}
func TestSmhasherAvalanche(t *TState) bool {
	if !HaveGoodHash() {
	}
	if Short() {
	}
	avalancheTest1(&BytesKey{make([]byte, 2)})
	avalancheTest1(&BytesKey{make([]byte, 4)})
	avalancheTest1(&BytesKey{make([]byte, 8)})
	avalancheTest1(&BytesKey{make([]byte, 16)})
	avalancheTest1(&BytesKey{make([]byte, 32)})
	avalancheTest1(&BytesKey{make([]byte, 200)})
	avalancheTest1(&Int32Key{})
	avalancheTest1(&Int64Key{})
	return false
}
func avalancheTest1(k Key) {
	const REP = 100000
	r := rand.New(rand.NewSource(1234))
	n := k.bits()
	fmt.Printf("\t\tz=%d, n=%d\n", REP, n)
	grid := make([][hashSize]int, n)
	for z := 0; z < REP; z++ {
		k.random(r)
		h := k.hash()
		for i := 0; i < n; i++ {
			k.flipBit(i)
			d := h ^ k.hash()
			k.flipBit(i)
			g := &grid[i]
			for j := 0; j < hashSize; j++ {
				g[j] += int(d & 1)
				d >>= 1
			}
		}
	}
	N := n * hashSize
	var c float64
	for c = 0.0; math.Pow(math.Erf(c/math.Sqrt(2)), float64(N)) < .9999; c += .1 {
	}
	c *= 4.0  
	mean := .5 * REP
	stddev := .5 * math.Sqrt(REP)
	low := int(mean - c*stddev)
	high := int(mean + c*stddev)
	for i := 0; i < n; i++ {
		for j := 0; j < hashSize; j++ {
			x := grid[i][j]
			if x < low || x > high {
			}
		}
	}
}
func TestSmhasherWindowed(t *TState) bool {
	windowed(&Int32Key{})
	windowed(&Int64Key{})
	windowed(&BytesKey{make([]byte, 128)})
	return false
}
func windowed(k Key) {
	if Short() {
	}
	const BITS = 16
	for r := 0; r < k.bits(); r++ {
		h := newHashSet()
		for i := 0; i < 1<<BITS; i++ {
			k.clear()
			for j := 0; j < BITS; j++ {
				if i>>uint(j)&1 != 0 {
					k.flipBit((j + r) % k.bits())
				}
			}
			h.add(k.hash())
		}
		h.check()
	}
}
func TestSmhasherText(t *TState) bool {
	if Short() {
	}
	text("Foo", "Bar")
	text("FooBar", "")
	text("", "FooBar")
	return false
}
func text(prefix, suffix string) {
	const N = 4
	const S = "ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst0123456789"
	const L = len(S)
	b := make([]byte, len(prefix)+N+len(suffix))
	copy(b, prefix)
	copy(b[len(prefix)+N:], suffix)
	h := newHashSet()
	c := b[len(prefix):]
	for i := 0; i < L; i++ {
		c[0] = S[i]
		for j := 0; j < L; j++ {
			c[1] = S[j]
			for k := 0; k < L; k++ {
				c[2] = S[k]
				for x := 0; x < L; x++ {
					c[3] = S[x]
					h.addB(b)
				}
			}
		}
	}
	h.check()
}