Added more tests
This commit is contained in:
parent
9f7388accc
commit
d7c37b9060
@ -8,10 +8,14 @@ import (
|
||||
)
|
||||
|
||||
func BenchmarkSize(b *testing.B) {
|
||||
b.Run("7", bench(7))
|
||||
b.Run("8", bench(8))
|
||||
b.Run("16", bench(16))
|
||||
b.Run("17", bench(17))
|
||||
b.Run("32", bench(32))
|
||||
b.Run("33", bench(33))
|
||||
b.Run("64", bench(64))
|
||||
b.Run("65", bench(65))
|
||||
b.Run("128", bench(128))
|
||||
b.Run("256", bench(256))
|
||||
b.Run("512", bench(512))
|
||||
|
4
hash.go
4
hash.go
@ -13,7 +13,7 @@ func add(x uint64, in []byte) uint64 {
|
||||
var i int
|
||||
|
||||
// Cache lines on modern processors are 64 bytes long.
|
||||
// A single uint64 consumes 64 bits (8 bytes).
|
||||
// A single uint64 consumes 8 bytes.
|
||||
// That means we should read 8 uint64 at a time.
|
||||
for ; i < len(in)-63; i += 64 {
|
||||
words := (*[8]uint64)(unsafe.Pointer(&in[i]))
|
||||
@ -46,5 +46,5 @@ func add(x uint64, in []byte) uint64 {
|
||||
}
|
||||
|
||||
func mix(x uint64, b uint64) uint64 {
|
||||
return (x + b) * 0x50003
|
||||
return (x + b) * 0xD0003
|
||||
}
|
||||
|
61
hash_test.go
61
hash_test.go
@ -7,42 +7,53 @@ import (
|
||||
"git.akyoto.dev/go/hash"
|
||||
)
|
||||
|
||||
// Hashes generated in tests will be saved to check for collisions.
|
||||
var hashes = map[uint64][]byte{}
|
||||
|
||||
func TestTinyCollisions(t *testing.T) {
|
||||
for size := 1; size < 8; size++ {
|
||||
tmp := make([]byte, size)
|
||||
index := 0
|
||||
// addHash adds a new hash and checks for collisions.
|
||||
func addHash(t *testing.T, sum uint64, data []byte) {
|
||||
saved, found := hashes[sum]
|
||||
|
||||
for i := 0; i < 256; i++ {
|
||||
tmp[index] += 1
|
||||
h := hash.Bytes(tmp)
|
||||
previous, found := hashes[h]
|
||||
if found && !bytes.Equal(saved, data) {
|
||||
t.Fatalf("collision between %v and %v:\nhash %064b", saved, data, sum)
|
||||
}
|
||||
|
||||
if found && !bytes.Equal(tmp, previous) {
|
||||
t.Fatalf("collision between %v and %v:\nhash %064b", previous, tmp, h)
|
||||
}
|
||||
save := make([]byte, len(data))
|
||||
copy(save, data)
|
||||
hashes[sum] = save
|
||||
}
|
||||
|
||||
save := make([]byte, size)
|
||||
copy(save, tmp)
|
||||
hashes[h] = save
|
||||
index = (index + 1) % size
|
||||
// TestTiny hashes every single permutation that is 1-32 bytes long.
|
||||
func TestTiny(t *testing.T) {
|
||||
for size := 1; size <= 32; size++ {
|
||||
data := make([]byte, size)
|
||||
|
||||
for i := 0; i <= 255*size; i++ {
|
||||
sum := hash.Bytes(data)
|
||||
addHash(t, sum, data)
|
||||
data[i%size] += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestZeroedCollisions(t *testing.T) {
|
||||
// TestZeroed hashes completely zeroed buffers that are 1-8192 bytes long.
|
||||
func TestZeroed(t *testing.T) {
|
||||
zero := make([]byte, 8192)
|
||||
|
||||
for size := 1; size <= len(zero); size++ {
|
||||
tmp := zero[:size]
|
||||
h := hash.Bytes(tmp)
|
||||
previous, found := hashes[h]
|
||||
|
||||
if found && !bytes.Equal(tmp, previous) {
|
||||
t.Fatalf("collision between %v and %v:\nhash %064b", previous, tmp, h)
|
||||
}
|
||||
|
||||
hashes[h] = tmp
|
||||
data := zero[:size]
|
||||
sum := hash.Bytes(data)
|
||||
addHash(t, sum, data)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSameByte hashes every byte repetition that is 1-512 bytes long.
|
||||
func TestSameByte(t *testing.T) {
|
||||
for b := 1; b < 256; b++ {
|
||||
for size := 1; size <= 512; size++ {
|
||||
data := bytes.Repeat([]byte{byte(b)}, size)
|
||||
sum := hash.Bytes(data)
|
||||
addHash(t, sum, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user