mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix fnv a hashes (#1667)
* fix fnv32a * fix fnv64a * Simplify code --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
@@ -8,7 +8,7 @@ distinct Fnv32a = uint;
|
|||||||
const FNV32A_START @private = 0x811c9dc5;
|
const FNV32A_START @private = 0x811c9dc5;
|
||||||
const FNV32A_MUL @private = 0x01000193;
|
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)
|
fn void Fnv32a.init(&self)
|
||||||
{
|
{
|
||||||
@@ -17,17 +17,17 @@ fn void Fnv32a.init(&self)
|
|||||||
|
|
||||||
fn void Fnv32a.update(&self, char[] data)
|
fn void Fnv32a.update(&self, char[] data)
|
||||||
{
|
{
|
||||||
uint h = (uint)*self;
|
Fnv32a h = *self;
|
||||||
foreach (char x : data)
|
foreach (char x : data)
|
||||||
{
|
{
|
||||||
@update(h, x);
|
@update(h, x);
|
||||||
}
|
}
|
||||||
*self = (Fnv32a)h;
|
*self = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro void Fnv32a.update_char(&self, char c)
|
macro void Fnv32a.update_char(&self, char c)
|
||||||
{
|
{
|
||||||
@update(*self, x);
|
@update(*self, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uint encode(char[] data)
|
fn uint encode(char[] data)
|
||||||
@@ -38,4 +38,4 @@ fn uint encode(char[] data)
|
|||||||
@update(h, x);
|
@update(h, x);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ distinct Fnv64a = ulong;
|
|||||||
const FNV64A_START @private = 0xcbf29ce484222325;
|
const FNV64A_START @private = 0xcbf29ce484222325;
|
||||||
const FNV64A_MUL @private = 0x00000100000001b3;
|
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)
|
fn void Fnv64a.init(&self)
|
||||||
{
|
{
|
||||||
@@ -17,17 +17,17 @@ fn void Fnv64a.init(&self)
|
|||||||
|
|
||||||
fn void Fnv64a.update(&self, char[] data)
|
fn void Fnv64a.update(&self, char[] data)
|
||||||
{
|
{
|
||||||
ulong h = (ulong)*self;
|
Fnv64a h = *self;
|
||||||
foreach (char x : data)
|
foreach (char x : data)
|
||||||
{
|
{
|
||||||
@update(h, x);
|
@update(h, x);
|
||||||
}
|
}
|
||||||
*self = (Fnv64a)h;
|
*self = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro void Fnv64a.update_char(&self, char c)
|
macro void Fnv64a.update_char(&self, char c)
|
||||||
{
|
{
|
||||||
@update(*self, x);
|
@update(*self, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ulong encode(char[] data)
|
fn ulong encode(char[] data)
|
||||||
@@ -38,4 +38,4 @@ fn ulong encode(char[] data)
|
|||||||
@update(h, x);
|
@update(h, x);
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|||||||
24
test/unit/stdlib/hash/fnv32a.c3
Normal file
24
test/unit/stdlib/hash/fnv32a.c3
Normal 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);
|
||||||
|
}
|
||||||
24
test/unit/stdlib/hash/fnv64a.c3
Normal file
24
test/unit/stdlib/hash/fnv64a.c3
Normal 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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user