Fix fnv a hashes (#1667)

* fix fnv32a

* fix fnv64a

* Simplify code

---------

Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
konimarti
2024-12-07 15:39:45 +01:00
committed by GitHub
parent ea86c9d37a
commit e67e9d3bbf
4 changed files with 58 additions and 10 deletions

View File

@@ -8,7 +8,7 @@ distinct Fnv32a = uint;
const FNV32A_START @private = 0x811c9dc5;
const FNV32A_MUL @private = 0x01000193;
macro void @update(uint* &h, char x) @private => *h = (*h * FNV32A_MUL) ^ x;
macro void @update(&h, char x) @private => *h = (*h ^ ($typeof(*h))x) * FNV32A_MUL;
fn void Fnv32a.init(&self)
{
@@ -17,17 +17,17 @@ fn void Fnv32a.init(&self)
fn void Fnv32a.update(&self, char[] data)
{
uint h = (uint)*self;
Fnv32a h = *self;
foreach (char x : data)
{
@update(h, x);
}
*self = (Fnv32a)h;
*self = h;
}
macro void Fnv32a.update_char(&self, char c)
{
@update(*self, x);
@update(*self, c);
}
fn uint encode(char[] data)
@@ -38,4 +38,4 @@ fn uint encode(char[] data)
@update(h, x);
}
return h;
}
}

View File

@@ -8,7 +8,7 @@ distinct Fnv64a = ulong;
const FNV64A_START @private = 0xcbf29ce484222325;
const FNV64A_MUL @private = 0x00000100000001b3;
macro void @update(ulong* &h, char x) @private => *h = (*h * FNV64A_MUL) ^ x;
macro void @update(&h, char x) @private => *h = (*h ^ ($typeof(*h))x) * FNV64A_MUL;
fn void Fnv64a.init(&self)
{
@@ -17,17 +17,17 @@ fn void Fnv64a.init(&self)
fn void Fnv64a.update(&self, char[] data)
{
ulong h = (ulong)*self;
Fnv64a h = *self;
foreach (char x : data)
{
@update(h, x);
}
*self = (Fnv64a)h;
*self = h;
}
macro void Fnv64a.update_char(&self, char c)
{
@update(*self, x);
@update(*self, c);
}
fn ulong encode(char[] data)
@@ -38,4 +38,4 @@ fn ulong encode(char[] data)
@update(h, x);
}
return h;
}
}

View File

@@ -0,0 +1,24 @@
module std::hash::fnv32a_test @test;
import std::hash::fnv32a;
fn void test_fnv32a()
{
Fnv32a hash;
char[] input = "Hello world";
uint want = 0x594d29c7;
// update
hash.init();
hash.update(input);
assert ((uint)hash == want, "got: %d, want: %d", hash, want);
// update_char
hash.init();
foreach (c : input) hash.update_char(c);
assert ((uint)hash == want, "got: %d, want: %d", hash, want);
// encode
uint encoded = fnv32a::encode(input);
assert (encoded == want, "got: %d, want: %d", encoded, want);
}

View File

@@ -0,0 +1,24 @@
module std::hash::fnv64a_test @test;
import std::hash::fnv64a;
fn void test_fnv64a()
{
Fnv64a hash;
char[] input = "Hello world";
ulong want = 0x2713f785a33764c7;
// update
hash.init();
hash.update(input);
assert ((ulong)hash == want, "got: %d, want: %d", hash, want);
// update_char
hash.init();
foreach (c : input) hash.update_char(c);
assert ((ulong)hash == want, "got: %d, want: %d", hash, want);
// encode
ulong encoded = fnv64a::encode(input);
assert (encoded == want, "got: %d, want: %d", encoded, want);
}