Port testing\core\hash

This commit is contained in:
Jeroen van Rijn
2024-05-30 18:05:09 +02:00
committed by Feoramund
parent 6f7c5a7577
commit 39fd73fe17
4 changed files with 302 additions and 312 deletions

View File

@@ -60,7 +60,7 @@ fmt_test:
$(ODIN) test fmt $(COMMON) -out:test_core_fmt
hash_test:
$(ODIN) run hash $(COMMON) -o:speed -out:test_hash
$(ODIN) test hash $(COMMON) -o:speed -out:test_hash
i18n_test:
$(ODIN) run text/i18n $(COMMON) -out:test_core_i18n

View File

@@ -47,7 +47,7 @@ echo ---
echo ---
echo Running core:hash tests
echo ---
%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_core_hash.exe || exit /b
%PATH_TO_ODIN% test hash %COMMON% -o:speed -out:test_core_hash.exe || exit /b
echo ---
echo Running core:image tests

View File

@@ -5,47 +5,314 @@ import "core:hash"
import "core:time"
import "core:testing"
import "core:fmt"
import "core:os"
import "core:log"
import "core:math/rand"
import "base:intrinsics"
TEST_count := 0
TEST_fail := 0
@test
test_xxhash_zero_fixed :: proc(t: ^testing.T) {
many_zeroes := make([]u8, 16 * 1024 * 1024)
defer delete(many_zeroes)
when ODIN_TEST {
expect :: testing.expect
log :: testing.log
} else {
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
TEST_count += 1
if !condition {
TEST_fail += 1
fmt.printf("[%v] %v\n", loc, message)
return
// All at once.
for i, v in ZERO_VECTORS {
b := many_zeroes[:i]
xxh32 := xxhash.XXH32(b)
xxh64 := xxhash.XXH64(b)
xxh3_64 := xxhash.XXH3_64(b)
xxh3_128 := xxhash.XXH3_128(b)
testing.expectf(t, xxh32 == v.xxh_32, "[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32)
testing.expectf(t, xxh64 == v.xxh_64, "[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64)
testing.expectf(t, xxh3_64 == v.xxh3_64, "[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64)
testing.expectf(t, xxh3_128 == v.xxh3_128, "[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128)
}
}
@(test)
test_xxhash_zero_streamed_random_updates :: proc(t: ^testing.T) {
many_zeroes := make([]u8, 16 * 1024 * 1024)
defer delete(many_zeroes)
// Streamed
for i, v in ZERO_VECTORS {
b := many_zeroes[:i]
xxh_32_state, xxh_32_err := xxhash.XXH32_create_state()
defer xxhash.XXH32_destroy_state(xxh_32_state)
testing.expect(t, xxh_32_err == nil, "Problem initializing XXH_32 state")
xxh_64_state, xxh_64_err := xxhash.XXH64_create_state()
defer xxhash.XXH64_destroy_state(xxh_64_state)
testing.expect(t, xxh_64_err == nil, "Problem initializing XXH_64 state")
xxh3_64_state, xxh3_64_err := xxhash.XXH3_create_state()
defer xxhash.XXH3_destroy_state(xxh3_64_state)
testing.expect(t, xxh3_64_err == nil, "Problem initializing XXH3_64 state")
xxh3_128_state, xxh3_128_err := xxhash.XXH3_create_state()
defer xxhash.XXH3_destroy_state(xxh3_128_state)
testing.expect(t, xxh3_128_err == nil, "Problem initializing XXH3_128 state")
// XXH3_128_update
random_seed := rand.create(t.seed)
for len(b) > 0 {
update_size := min(len(b), rand.int_max(8192, &random_seed))
if update_size > 4096 {
update_size %= 73
}
xxhash.XXH32_update (xxh_32_state, b[:update_size])
xxhash.XXH64_update (xxh_64_state, b[:update_size])
xxhash.XXH3_64_update (xxh3_64_state, b[:update_size])
xxhash.XXH3_128_update(xxh3_128_state, b[:update_size])
b = b[update_size:]
}
// Now finalize
xxh32 := xxhash.XXH32_digest(xxh_32_state)
xxh64 := xxhash.XXH64_digest(xxh_64_state)
xxh3_64 := xxhash.XXH3_64_digest(xxh3_64_state)
xxh3_128 := xxhash.XXH3_128_digest(xxh3_128_state)
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32)
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64)
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128)
testing.expect(t, xxh32 == v.xxh_32, xxh32_error)
testing.expect(t, xxh64 == v.xxh_64, xxh64_error)
testing.expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
testing.expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
}
}
@test
test_xxhash_seeded :: proc(t: ^testing.T) {
buf := make([]u8, 256)
defer delete(buf)
for seed, table in XXHASH_TEST_VECTOR_SEEDED {
for v, i in table {
b := buf[:i]
xxh32 := xxhash.XXH32(b, u32(seed))
xxh64 := xxhash.XXH64(b, seed)
xxh3_64 := xxhash.XXH3_64(b, seed)
xxh3_128 := xxhash.XXH3_128(b, seed)
testing.expectf(t, xxh32 == v.xxh_32, "[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32)
testing.expectf(t, xxh64 == v.xxh_64, "[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64)
testing.expectf(t, xxh3_64 == v.xxh3_64, "[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64)
testing.expectf(t, xxh3_128 == v.xxh3_128, "[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128)
if len(b) > xxhash.XXH3_MIDSIZE_MAX {
xxh3_state, _ := xxhash.XXH3_create_state()
xxhash.XXH3_64_reset_with_seed(xxh3_state, seed)
xxhash.XXH3_64_update(xxh3_state, b)
xxh3_64_streamed := xxhash.XXH3_64_digest(xxh3_state)
xxhash.XXH3_destroy_state(xxh3_state)
testing.expectf(t, xxh3_64_streamed == v.xxh3_64, "[XXH3_64s(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64_streamed)
xxh3_state2, _ := xxhash.XXH3_create_state()
xxhash.XXH3_128_reset_with_seed(xxh3_state2, seed)
xxhash.XXH3_128_update(xxh3_state2, b)
xxh3_128_streamed := xxhash.XXH3_128_digest(xxh3_state2)
xxhash.XXH3_destroy_state(xxh3_state2)
testing.expectf(t, xxh3_128_streamed == v.xxh3_128, "[XXH3_128s(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128_streamed)
}
}
}
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
fmt.printf("[%v] ", loc)
fmt.printf("log: %v\n", v)
}
@test
test_xxhash_secret :: proc(t: ^testing.T) {
buf := make([]u8, 256)
defer delete(buf)
for secret, table in XXHASH_TEST_VECTOR_SECRET {
secret_bytes := transmute([]u8)secret
for v, i in table {
b := buf[:i]
xxh3_128 := xxhash.XXH3_128(b, secret_bytes)
testing.expectf(t, xxh3_128 == v.xxh3_128_secret, "[XXH3_128(%03d)] Expected: %32x, got: %32x", i, v.xxh3_128_secret, xxh3_128)
}
}
}
main :: proc() {
t := testing.T{}
test_benchmark_runner(&t)
test_crc64_vectors(&t)
test_xxhash_vectors(&t)
test_xxhash_large(&t)
@test
test_crc64_vectors :: proc(t: ^testing.T) {
vectors := map[string][4]u64 {
"123456789" = {
0x6c40df5f0b497347, // ECMA-182,
0x995dc9bbdf1939fa, // XZ
0x46a5a9388a5beffe, // ISO 3306
0xb90956c775a41001, // ISO 3306, input and output inverted
},
"This is a test of the emergency broadcast system." = {
0x344fe1d09c983d13, // ECMA-182
0x27db187fc15bbc72, // XZ
0x187184d744afc49e, // ISO 3306
0xe7fcf1006b503b61, // ISO 3306, input and output inverted
},
}
defer delete(vectors)
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
if TEST_fail > 0 {
os.exit(1)
for vector, expected in vectors {
b := transmute([]u8)vector
ecma := hash.crc64_ecma_182(b)
xz := hash.crc64_xz(b)
iso := hash.crc64_iso_3306(b)
iso2 := hash.crc64_iso_3306_inverse(b)
testing.expectf(t, ecma == expected[0], "[ CRC-64 ECMA ] Expected: %016x, got: %016x", expected[0], ecma)
testing.expectf(t, xz == expected[1], "[ CRC-64 XZ ] Expected: %016x, got: %016x", expected[1], xz)
testing.expectf(t, iso == expected[2], "[ CRC-64 ISO 3306] Expected: %016x, got: %016x", expected[2], iso)
testing.expectf(t, iso2 == expected[3], "[~CRC-64 ISO 3306] Expected: %016x, got: %016x", expected[3], iso2)
}
}
/*
Benchmarks
*/
@(test)
test_benchmark_xxh32 :: proc(t: ^testing.T) {
name := "XXH32 100 zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 100,
setup = setup_xxhash,
bench = benchmark_xxh32,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0x85f6413c)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
@(test)
test_benchmark_xxh32_1MB :: proc(t: ^testing.T) {
name := "XXH32 1 MiB zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 1_048_576,
setup = setup_xxhash,
bench = benchmark_xxh32,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0x9430f97f)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
@(test)
test_benchmark_xxh64 :: proc(t: ^testing.T) {
name := "XXH64 100 zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 100,
setup = setup_xxhash,
bench = benchmark_xxh64,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0x17bb1103c92c502f)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
@(test)
test_benchmark_xxh64_1MB :: proc(t: ^testing.T) {
name := "XXH64 1 MiB zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 1_048_576,
setup = setup_xxhash,
bench = benchmark_xxh64,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0x87d2a1b6e1163ef1)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
@(test)
test_benchmark_xxh3_64 :: proc(t: ^testing.T) {
name := "XXH3_64 100 zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 100,
setup = setup_xxhash,
bench = benchmark_xxh3_64,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0x801fedc74ccd608c)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
@(test)
test_benchmark_xxh3_64_1MB :: proc(t: ^testing.T) {
name := "XXH3_64 1 MiB zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 1_048_576,
setup = setup_xxhash,
bench = benchmark_xxh3_64,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0x918780b90550bf34)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
@(test)
test_benchmark_xxh3_128 :: proc(t: ^testing.T) {
name := "XXH3_128 100 zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 100,
setup = setup_xxhash,
bench = benchmark_xxh3_128,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0x6ba30a4e9dffe1ff801fedc74ccd608c)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
@(test)
test_benchmark_xxh3_128_1MB :: proc(t: ^testing.T) {
name := "XXH3_128 1 MiB zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 1_048_576,
setup = setup_xxhash,
bench = benchmark_xxh3_128,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
testing.expectf(t, err == nil, "%s failed with err %v", name, err)
hash := u128(0xb6ef17a3448492b6918780b90550bf34)
testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash)
benchmark_print(name, options)
}
// Benchmarks
setup_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
assert(options != nil)
@@ -113,289 +380,14 @@ benchmark_xxh3_128 :: proc(options: ^time.Benchmark_Options, allocator := contex
return nil
}
benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
fmt.printf("\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
benchmark_print :: proc(name: string, options: ^time.Benchmark_Options, loc := #caller_location) {
log.infof("\n\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s",
name,
options.rounds,
options.processed,
time.duration_nanoseconds(options.duration),
options.rounds_per_second,
options.megabytes_per_second,
location=loc,
)
}
@test
test_benchmark_runner :: proc(t: ^testing.T) {
fmt.println("Starting benchmarks:")
name := "XXH32 100 zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 100,
setup = setup_xxhash,
bench = benchmark_xxh32,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x85f6413c, name)
benchmark_print(name, options)
name = "XXH32 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x9430f97f, name)
benchmark_print(name, options)
name = "XXH64 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh64
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x17bb1103c92c502f, name)
benchmark_print(name, options)
name = "XXH64 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x87d2a1b6e1163ef1, name)
benchmark_print(name, options)
name = "XXH3_64 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh3_64
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x801fedc74ccd608c, name)
benchmark_print(name, options)
name = "XXH3_64 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x918780b90550bf34, name)
benchmark_print(name, options)
name = "XXH3_128 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh3_128
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x6ba30a4e9dffe1ff801fedc74ccd608c, name)
benchmark_print(name, options)
name = "XXH3_128 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0xb6ef17a3448492b6918780b90550bf34, name)
benchmark_print(name, options)
}
@test
test_xxhash_large :: proc(t: ^testing.T) {
many_zeroes := make([]u8, 16 * 1024 * 1024)
defer delete(many_zeroes)
// All at once.
for i, v in ZERO_VECTORS {
b := many_zeroes[:i]
fmt.printf("[test_xxhash_large] All at once. Size: %v\n", i)
xxh32 := xxhash.XXH32(b)
xxh64 := xxhash.XXH64(b)
xxh3_64 := xxhash.XXH3_64(b)
xxh3_128 := xxhash.XXH3_128(b)
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
expect(t, xxh32 == v.xxh_32, xxh32_error)
expect(t, xxh64 == v.xxh_64, xxh64_error)
expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
}
when #config(RAND_STATE, -1) >= 0 && #config(RAND_INC, -1) >= 0 {
random_seed := rand.Rand{
state = u64(#config(RAND_STATE, -1)),
inc = u64(#config(RAND_INC, -1)),
}
fmt.printf("Using user-selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc)
} else {
random_seed := rand.create(u64(intrinsics.read_cycle_counter()))
fmt.printf("Randonly selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc)
}
// Streamed
for i, v in ZERO_VECTORS {
b := many_zeroes[:i]
fmt.printf("[test_xxhash_large] Streamed. Size: %v\n", i)
// bytes_per_update := []int{1, 42, 13, 7, 16, 5, 23, 74, 1024, 511, 1023, 47}
// update_size_idx: int
xxh_32_state, xxh_32_err := xxhash.XXH32_create_state()
defer xxhash.XXH32_destroy_state(xxh_32_state)
expect(t, xxh_32_err == nil, "Problem initializing XXH_32 state.")
xxh_64_state, xxh_64_err := xxhash.XXH64_create_state()
defer xxhash.XXH64_destroy_state(xxh_64_state)
expect(t, xxh_64_err == nil, "Problem initializing XXH_64 state.")
xxh3_64_state, xxh3_64_err := xxhash.XXH3_create_state()
defer xxhash.XXH3_destroy_state(xxh3_64_state)
expect(t, xxh3_64_err == nil, "Problem initializing XXH3_64 state.")
xxh3_128_state, xxh3_128_err := xxhash.XXH3_create_state()
defer xxhash.XXH3_destroy_state(xxh3_128_state)
expect(t, xxh3_128_err == nil, "Problem initializing XXH3_128 state.")
// XXH3_128_update
for len(b) > 0 {
update_size := min(len(b), rand.int_max(8192, &random_seed))
if update_size > 4096 {
update_size %= 73
}
xxhash.XXH32_update (xxh_32_state, b[:update_size])
xxhash.XXH64_update (xxh_64_state, b[:update_size])
xxhash.XXH3_64_update (xxh3_64_state, b[:update_size])
xxhash.XXH3_128_update(xxh3_128_state, b[:update_size])
b = b[update_size:]
}
// Now finalize
xxh32 := xxhash.XXH32_digest(xxh_32_state)
xxh64 := xxhash.XXH64_digest(xxh_64_state)
xxh3_64 := xxhash.XXH3_64_digest(xxh3_64_state)
xxh3_128 := xxhash.XXH3_128_digest(xxh3_128_state)
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
expect(t, xxh32 == v.xxh_32, xxh32_error)
expect(t, xxh64 == v.xxh_64, xxh64_error)
expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
}
}
@test
test_xxhash_vectors :: proc(t: ^testing.T) {
fmt.println("Verifying against XXHASH_TEST_VECTOR_SEEDED:")
buf := make([]u8, 256)
defer delete(buf)
for seed, table in XXHASH_TEST_VECTOR_SEEDED {
fmt.printf("\tSeed: %v\n", seed)
for v, i in table {
b := buf[:i]
xxh32 := xxhash.XXH32(b, u32(seed))
xxh64 := xxhash.XXH64(b, seed)
xxh3_64 := xxhash.XXH3_64(b, seed)
xxh3_128 := xxhash.XXH3_128(b, seed)
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
expect(t, xxh32 == v.xxh_32, xxh32_error)
expect(t, xxh64 == v.xxh_64, xxh64_error)
expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
if len(b) > xxhash.XXH3_MIDSIZE_MAX {
fmt.printf("XXH3 - size: %v\n", len(b))
xxh3_state, _ := xxhash.XXH3_create_state()
xxhash.XXH3_64_reset_with_seed(xxh3_state, seed)
xxhash.XXH3_64_update(xxh3_state, b)
xxh3_64_streamed := xxhash.XXH3_64_digest(xxh3_state)
xxhash.XXH3_destroy_state(xxh3_state)
xxh3_64s_error := fmt.tprintf("[XXH3_64s(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64_streamed)
expect(t, xxh3_64_streamed == v.xxh3_64, xxh3_64s_error)
xxh3_state2, _ := xxhash.XXH3_create_state()
xxhash.XXH3_128_reset_with_seed(xxh3_state2, seed)
xxhash.XXH3_128_update(xxh3_state2, b)
xxh3_128_streamed := xxhash.XXH3_128_digest(xxh3_state2)
xxhash.XXH3_destroy_state(xxh3_state2)
xxh3_128s_error := fmt.tprintf("[XXH3_128s(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128_streamed)
expect(t, xxh3_128_streamed == v.xxh3_128, xxh3_128s_error)
}
}
}
fmt.println("Verifying against XXHASH_TEST_VECTOR_SECRET:")
for secret, table in XXHASH_TEST_VECTOR_SECRET {
fmt.printf("\tSecret:\n\t\t\"%v\"\n", secret)
secret_bytes := transmute([]u8)secret
for v, i in table {
b := buf[:i]
xxh3_128 := xxhash.XXH3_128(b, secret_bytes)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d)] Expected: %32x. Got: %32x.", i, v.xxh3_128_secret, xxh3_128)
expect(t, xxh3_128 == v.xxh3_128_secret, xxh3_128_error)
}
}
}
@test
test_crc64_vectors :: proc(t: ^testing.T) {
fmt.println("Verifying CRC-64:")
vectors := map[string][4]u64 {
"123456789" = {
0x6c40df5f0b497347, // ECMA-182,
0x995dc9bbdf1939fa, // XZ
0x46a5a9388a5beffe, // ISO 3306
0xb90956c775a41001, // ISO 3306, input and output inverted
},
"This is a test of the emergency broadcast system." = {
0x344fe1d09c983d13, // ECMA-182
0x27db187fc15bbc72, // XZ
0x187184d744afc49e, // ISO 3306
0xe7fcf1006b503b61, // ISO 3306, input and output inverted
},
}
for vector, expected in vectors {
fmt.println("\tVector:", vector)
b := transmute([]u8)vector
ecma := hash.crc64_ecma_182(b)
xz := hash.crc64_xz(b)
iso := hash.crc64_iso_3306(b)
iso2 := hash.crc64_iso_3306_inverse(b)
ecma_error := fmt.tprintf("[ CRC-64 ECMA ] Expected: %016x. Got: %016x.", expected[0], ecma)
xz_error := fmt.tprintf("[ CRC-64 XZ ] Expected: %016x. Got: %016x.", expected[1], xz)
iso_error := fmt.tprintf("[ CRC-64 ISO 3306] Expected: %016x. Got: %016x.", expected[2], iso)
iso2_error := fmt.tprintf("[~CRC-64 ISO 3306] Expected: %016x. Got: %016x.", expected[3], iso2)
expect(t, ecma == expected[0], ecma_error)
expect(t, xz == expected[1], xz_error)
expect(t, iso == expected[2], iso_error)
expect(t, iso2 == expected[3], iso2_error)
}
}

View File

@@ -1,6 +1,4 @@
/*
Hash Test Vectors
*/
// Hash Test Vectors
package test_core_hash
XXHASH_Test_Vectors :: struct #packed {
@@ -6789,4 +6787,4 @@ XXHASH_TEST_VECTOR_SECRET := map[string][257]XXHASH_Test_Vectors_With_Secret{
/* XXH3_128_with_secret */ 0x0f9b41191242ade48bbde48dff0d38ec,
},
},
}
}