-
Notifications
You must be signed in to change notification settings - Fork 0
/
hashes.kai
76 lines (62 loc) · 1.55 KB
/
hashes.kai
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
Fnv64a :: fn(buff: []u8) -> u64 {
h: u64 = 0xcbf29ce484222325
for c in buff {
h = (h ^ cast(u64)c) * 0x100000001b3
}
return h
}
Murmur332 :: fn(key: []u8, seed: u32) -> u32 {
data := key
blockCount := data.len / 4
h1 := seed
c1, c2: u32 = 0xcc9e2d51, 0x1b873593
end := &data.raw[blockCount * 4]
blocks : *u32 = autocast end
for i := -blockCount; i != 0; i += 1 {
k1 := blocks[i]
k1 *= c1
k1 = (k1 << 15) | (k1 >> (32 - 15))
k1 *= c2
h1 ^= k1
h1 = (h1 << 13) | (h1 >> (32 - 13))
h1 = h1*5+0xe6546b64
}
tail := &data.raw[blockCount*4]
k1: u32 = 0
switch data.len & 3 {
case 3:
k1 ^= cast(u32)tail[2] << 16
fallthrough
case 2:
k1 ^= cast(u32)tail[1] << 8
fallthrough
case 1:
k1 ^= cast(u32)tail[0]
k1 *= c1
k1 = (k1 << 15) | (k1 >> (32 - 15))
k1 *= c2
h1 ^= k1
}
h1 ^= cast(u32)data.len
h1 ^= h1 >> 16
h1 *= 0x85ebca6b
h1 ^= h1 >> 13
h1 *= 0xc2b2ae35
h1 ^= h1 >> 16
return h1
}
#test "FNV64a basic hash" {
hash := Fnv64a("Test")
assert(hash == 0x2474e7fb1aec9f05)
}
#test "Murmur3 32bit - 1234 seed" {
hash := Murmur332("Hello, world!", 1234)
assert(hash == 0xfaf6cdb3)
hash = Murmur332("xxxxxxxxxxxxxxxxxxxxxxxxxxxx", 1234)
assert(hash == 0x8905ac28)
hash = Murmur332("", 1234)
assert(hash == 0x0f2cc00b)
}
#test "Murmur3 32bit - 4321 seed" {
hash := Murmur332("Hello, world!", 0xbf505788)
}