// Expect retcode = 0 // 哈希工具:FNV-1a 字节哈希 + 整型混合;并给出可直接交给 map 的回调 // (map 的 hash/eq 回调接收指向键字节的指针,这里按 usize / ByteView 解释)。 // 仅提供确定性哈希与等值,不承诺密码学性质。 type .{ .ByteView } = @import("byte_view.spl"); // FNV-1a 64 位,逐字节;空输入返回 offset basis。 fn hash_bytes(data: *u8, len: usize): usize { var h: usize = 14695981039346656037; var i: usize = 0; while i < len { h = (h ^ (data[i] as usize)) * 1099511628211; i = i + 1; } ret h; } fn hash_byte_view(view: ByteView): usize { ret hash_bytes(view.ptr, view.len); } // 整型混合(splitmix 风格的移位-乘法),保证非零与良好扩散。 fn hash_usize_value(value: usize): usize { var h = value; h = (h ^ (h >> 30)) * 1099511628211; h = h ^ (h >> 27); h = h * 1099511628211; h = h ^ (h >> 31); if h == 0 { ret 1099511628211; } // 0 映射到非零 ret h; } // ---- map 回调 ---- // 键按 usize 解释。 fn hash_usize(key: *u8): usize { ret hash_usize_value((key as *usize).*); } fn eq_usize(a: *u8, b: *u8): bool { ret (a as *usize).* == (b as *usize).*; } // 键按 ByteView 解释,哈希其指向的字节。 fn hash_view(key: *u8): usize { var view = (key as *ByteView).*; ret hash_byte_view(view); } fn eq_view(a: *u8, b: *u8): bool { ret ByteView.eq((a as *ByteView).*, (b as *ByteView).*); } // ---- 测试辅助 ---- fn expect_hash(view: []u8, expected: usize) { var got = hash_bytes(view.ptr, view.len); @assert(got == expected, "hash value"); } fn test_fnv_vectors() { expect_hash("", 14695981039346656037); expect_hash("a", 12638187200555641996); expect_hash("foobar", 9625390261332436968); expect_hash("hello", 11831194018420276491); // 同一输入稳定;不同输入不同。 var s1: []u8 = "abc"; var s2: []u8 = "abd"; @assert(hash_bytes(s1.ptr, 3) == hash_bytes(s1.ptr, 3), "deterministic"); @assert(hash_bytes(s1.ptr, 3) != hash_bytes(s2.ptr, 3), "distinct"); // ByteView 与 bytes 一致。 var v = ByteView.from_slice("foobar"); @assert(hash_byte_view(v) == hash_bytes(v.ptr, v.len), "view == bytes"); // 整型混合:0 不保持 0,且稳定/区分。 @assert(hash_usize_value(0) != 0, "zero mixed"); @assert(hash_usize_value(7) == hash_usize_value(7), "int stable"); @assert(hash_usize_value(7) != hash_usize_value(8), "int distinct"); } // map 回调(hash_usize/eq_usize/hash_view/eq_view)由 map.spl 在自己的测试里验证。 fn main() { test_fnv_vectors(); }