diff --git a/vlib/hash/fnv1a/fnv1a.v b/vlib/hash/fnv1a/fnv1a.v index 73d0899ac6..ffe1384350 100644 --- a/vlib/hash/fnv1a/fnv1a.v +++ b/vlib/hash/fnv1a/fnv1a.v @@ -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(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(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 +} diff --git a/vlib/hash/fnv1a/fnv1a_test.v b/vlib/hash/fnv1a/fnv1a_test.v index 9a979b6737..4c5dc762ac 100644 --- a/vlib/hash/fnv1a/fnv1a_test.v +++ b/vlib/hash/fnv1a/fnv1a_test.v @@ -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 }