| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- const std = @import("std");
- pub fn hashKey(k: []const u8) u32 {
- return fnv1a(k);
- }
- pub fn fnv1a(key: []const u8) u32 {
- var hash: u32 = 2166136261;
- for (key) |c| {
- hash ^= c;
- hash *%= 16777619;
- }
- return hash;
- }
- pub fn xoramasrosas(k: []const u8) u32 {
- var hash: u32 = 17 * 22;
- const x = "xoramasrosas";
- for (k, 0..) |char, i| {
- hash = hash +% (char ^ x[i % 12]) << 12;
- }
- return hash;
- }
- pub fn djb2(key: []const u8) u32 {
- var hash: u32 = 5381;
- for (key) |c| {
- hash = ((hash << 5) +% hash) +% c;
- }
- return hash;
- }
- test "fnv1a known values" {
- // FNV-1a 32-bit test vectors
- try std.testing.expectEqual(@as(u32, 2166136261), fnv1a(""));
- try std.testing.expect(fnv1a("hello") != fnv1a("world"));
- try std.testing.expect(fnv1a("hello") != fnv1a("Hello"));
- }
- test "fnv1a deterministic" {
- const h1 = fnv1a("test_key");
- const h2 = fnv1a("test_key");
- try std.testing.expectEqual(h1, h2);
- }
- test "hashKey delegates to fnv1a" {
- try std.testing.expectEqual(fnv1a("mykey"), hashKey("mykey"));
- }
- test "djb2 known values" {
- try std.testing.expectEqual(@as(u32, 5381), djb2(""));
- try std.testing.expect(djb2("hello") != djb2("world"));
- }
- test "djb2 deterministic" {
- try std.testing.expectEqual(djb2("abc"), djb2("abc"));
- }
- test "xoramasrosas deterministic" {
- try std.testing.expectEqual(xoramasrosas("key"), xoramasrosas("key"));
- try std.testing.expect(xoramasrosas("a") != xoramasrosas("b"));
- }
- test "different hash functions produce different results" {
- const key = "pizzakv";
- const f = fnv1a(key);
- const d = djb2(key);
- const x = xoramasrosas(key);
- // They should generally differ (not a guarantee but practically true)
- try std.testing.expect(f != d or f != x or d != x);
- }
- test "hash distribution - no trivial collisions for short keys" {
- const keys = [_][]const u8{ "a", "b", "c", "d", "e", "f", "g", "h" };
- var hashes: [8]u32 = undefined;
- for (keys, 0..) |k, i| {
- hashes[i] = fnv1a(k);
- }
- // All hashes should be unique for single-char keys
- for (0..8) |i| {
- for (i + 1..8) |j| {
- try std.testing.expect(hashes[i] != hashes[j]);
- }
- }
- }
|