aboutsummaryrefslogtreecommitdiff
path: root/lib/std/hash/verify.zig
diff options
context:
space:
mode:
authorMarc Tiehuis <marc@tiehu.is>2023-09-01 19:09:05 +1200
committerMarc Tiehuis <marc@tiehu.is>2023-09-02 15:37:49 +1200
commit26d61812a8dbad204517d00d3a1f0e52275eceeb (patch)
treeeffc228521adc62aa18e87565be05414e7c11aa2 /lib/std/hash/verify.zig
parentbb2eb4443034d0a8c051f5eef184062078502ae8 (diff)
downloadzig-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.zig35
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..]));
+}