hash.fnv1a: add generic fnv1a.sum64_struct/1 and fnv1a.sum32_struct/1 + tests

pull/12995/head
Delyan Angelov 2021-12-29 12:03:24 +02:00
parent 7c78bf9466
commit 69c90ef50d
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 62 additions and 0 deletions

View File

@ -31,6 +31,18 @@ pub fn sum32(data []byte) u32 {
return hash
}
// sum32_bytes returns a fnv1a hash of the struct `s`.
[direct_array_access; inline]
pub fn sum32_struct<T>(s &T) u32 {
bp := unsafe { &byte(s) }
sz := int(sizeof(T))
mut hash := fnv1a.fnv32_offset_basis
for i in 0 .. sz {
hash = unsafe { (hash ^ u32(bp[i])) * fnv1a.fnv32_prime }
}
return hash
}
// sum32_bytes returns a fnv1a hash of `data_len` bytes starting at
// the address in the given &byte pointer `data`.
[direct_array_access; inline; unsafe]
@ -73,3 +85,15 @@ pub fn sum64_bytes(data &byte, data_len int) u64 {
}
return hash
}
// sum64_bytes returns a fnv1a hash of the struct `s`.
[direct_array_access; inline]
pub fn sum64_struct<T>(s &T) u64 {
bp := unsafe { &byte(s) }
sz := int(sizeof(T))
mut hash := fnv1a.fnv64_offset_basis
for i in 0 .. sz {
hash = unsafe { (hash ^ u64(bp[i])) * fnv1a.fnv64_prime }
}
return hash
}

View File

@ -1,5 +1,17 @@
import hash.fnv1a
struct MyStruct {
mut:
x int
y int
z int
}
struct Abc {
mut:
a [5]u64
}
fn test_fnv1a_sum32() {
$if windows {
return
@ -12,6 +24,19 @@ fn test_fnv1a_sum32() {
assert b.hex() == ahash
assert c.hex() == ahash
assert d.hex() == ahash
//
mut aa := Abc{}
x := fnv1a.sum32_struct(aa)
aa.a[3] = 5
y := fnv1a.sum32_struct(aa)
assert x != y
mut ms := MyStruct{}
xx := fnv1a.sum32_struct(ms)
ms.x = 77
yy := fnv1a.sum32_struct(ms)
assert xx != yy
assert x != xx
assert y != yy
}
fn test_fnv1a_sum64() {
@ -26,4 +51,17 @@ fn test_fnv1a_sum64() {
assert b.hex() == ahash
assert c.hex() == ahash
assert d.hex() == ahash
//
mut aa := Abc{}
x := fnv1a.sum64_struct(aa)
aa.a[3] = 5
y := fnv1a.sum64_struct(aa)
assert x != y
mut ms := MyStruct{}
xx := fnv1a.sum64_struct(ms)
ms.x = 77
yy := fnv1a.sum64_struct(ms)
assert xx != yy
assert x != xx
assert y != yy
}