diff options
| author | Marc Tiehuis <marc@tiehu.is> | 2023-09-01 19:09:05 +1200 |
|---|---|---|
| committer | Marc Tiehuis <marc@tiehu.is> | 2023-09-02 15:37:49 +1200 |
| commit | 26d61812a8dbad204517d00d3a1f0e52275eceeb (patch) | |
| tree | effc228521adc62aa18e87565be05414e7c11aa2 /lib/std/hash/verify.zig | |
| parent | bb2eb4443034d0a8c051f5eef184062078502ae8 (diff) | |
| download | zig-26d61812a8dbad204517d00d3a1f0e52275eceeb.tar.gz zig-26d61812a8dbad204517d00d3a1f0e52275eceeb.zip | |
std/hash: add smhasher verification tests
Not all hashes are added just yet as these need to be generated manually
from reference implementations as they are not included by default in
smhasher.
Diffstat (limited to 'lib/std/hash/verify.zig')
| -rw-r--r-- | lib/std/hash/verify.zig | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/std/hash/verify.zig b/lib/std/hash/verify.zig new file mode 100644 index 0000000000..bfc6a1f22c --- /dev/null +++ b/lib/std/hash/verify.zig @@ -0,0 +1,35 @@ +const std = @import("std"); + +fn hashMaybeSeed(comptime hash_fn: anytype, seed: anytype, buf: []const u8) @typeInfo(@TypeOf(hash_fn)).Fn.return_type.? { + const HashFn = @typeInfo(@TypeOf(hash_fn)).Fn; + if (HashFn.params.len > 1) { + if (@typeInfo(HashFn.params[0].type.?) == .Int) { + return hash_fn(@intCast(seed), buf); + } else { + return hash_fn(buf, @intCast(seed)); + } + } else { + return hash_fn(buf); + } +} + +// Returns a verification code, the same as user by SMHasher. +// +// Hash keys of the form {0}, {0,1}, {0,1,2}... up to N=255, using 256-N as seed. +// First four-bytes of the hash, interpreted as little-endian is the verification code. +pub fn smhasher(comptime hash_fn: anytype) u32 { + const HashFnTy = @typeInfo(@TypeOf(hash_fn)).Fn; + const HashResult = HashFnTy.return_type.?; + const hash_size = @sizeOf(HashResult); + + var buf: [256]u8 = undefined; + var buf_all: [256 * hash_size]u8 = undefined; + + for (0..256) |i| { + buf[i] = @intCast(i); + const h = hashMaybeSeed(hash_fn, 256 - i, buf[0..i]); + std.mem.writeIntLittle(HashResult, buf_all[i * hash_size ..][0..hash_size], h); + } + + return @truncate(hashMaybeSeed(hash_fn, 0, buf_all[0..])); +} |
