2018-04-06 04:10:54 -07:00
|
|
|
// FNV1a - Fowler-Noll-Vo hash function
|
|
|
|
//
|
|
|
|
// FNV1a is a fast, non-cryptographic hash function with fairly good distribution properties.
|
|
|
|
//
|
|
|
|
// https://tools.ietf.org/html/draft-eastlake-fnv-14
|
|
|
|
|
|
|
|
const std = @import("../index.zig");
|
|
|
|
const debug = std.debug;
|
|
|
|
|
2018-05-28 17:23:55 -07:00
|
|
|
pub const Fnv1a_32 = Fnv1a(u32, 0x01000193, 0x811c9dc5);
|
2018-04-06 04:10:54 -07:00
|
|
|
pub const Fnv1a_64 = Fnv1a(u64, 0x100000001b3, 0xcbf29ce484222325);
|
|
|
|
pub const Fnv1a_128 = Fnv1a(u128, 0x1000000000000000000013b, 0x6c62272e07bb014262b821756295c58d);
|
|
|
|
|
|
|
|
fn Fnv1a(comptime T: type, comptime prime: T, comptime offset: T) type {
|
2018-11-13 05:08:37 -08:00
|
|
|
return struct {
|
2018-09-13 13:34:33 -07:00
|
|
|
const Self = @This();
|
2018-04-06 04:10:54 -07:00
|
|
|
|
|
|
|
value: T,
|
|
|
|
|
|
|
|
pub fn init() Self {
|
2018-11-13 05:08:37 -08:00
|
|
|
return Self{ .value = offset };
|
2018-04-06 04:10:54 -07:00
|
|
|
}
|
|
|
|
|
2018-05-31 07:56:59 -07:00
|
|
|
pub fn update(self: *Self, input: []const u8) void {
|
2018-04-06 04:10:54 -07:00
|
|
|
for (input) |b| {
|
|
|
|
self.value ^= b;
|
|
|
|
self.value *%= prime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-31 07:56:59 -07:00
|
|
|
pub fn final(self: *Self) T {
|
2018-04-06 04:10:54 -07:00
|
|
|
return self.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn hash(input: []const u8) T {
|
|
|
|
var c = Self.init();
|
|
|
|
c.update(input);
|
|
|
|
return c.final();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
test "fnv1a-32" {
|
|
|
|
debug.assert(Fnv1a_32.hash("") == 0x811c9dc5);
|
|
|
|
debug.assert(Fnv1a_32.hash("a") == 0xe40c292c);
|
|
|
|
debug.assert(Fnv1a_32.hash("foobar") == 0xbf9cf968);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "fnv1a-64" {
|
|
|
|
debug.assert(Fnv1a_64.hash("") == 0xcbf29ce484222325);
|
|
|
|
debug.assert(Fnv1a_64.hash("a") == 0xaf63dc4c8601ec8c);
|
|
|
|
debug.assert(Fnv1a_64.hash("foobar") == 0x85944171f73967e8);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "fnv1a-128" {
|
|
|
|
debug.assert(Fnv1a_128.hash("") == 0x6c62272e07bb014262b821756295c58d);
|
|
|
|
debug.assert(Fnv1a_128.hash("a") == 0xd228cb696f1a8caf78912b704e4a8964);
|
|
|
|
}
|