| 1 | module fnv1a |
| 2 | |
| 3 | // This module implements a FNV-1a hash. |
| 4 | // (see https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function) |
| 5 | |
| 6 | const fnv64_prime = u64(1099511628211) |
| 7 | const fnv64_offset_basis = u64(14695981039346656037) |
| 8 | const fnv32_offset_basis = u32(2166136261) |
| 9 | const fnv32_prime = u32(16777619) |
| 10 | |
| 11 | // sum32 returns a fnv1a hash of the string, described by `data` |
| 12 | @[direct_array_access; inline] |
| 13 | pub fn sum32_string(data string) u32 { |
| 14 | mut hash := fnv32_offset_basis |
| 15 | for i in 0 .. data.len { |
| 16 | hash = (hash ^ u32(data[i])) * fnv32_prime |
| 17 | } |
| 18 | return hash |
| 19 | } |
| 20 | |
| 21 | // sum32 returns a fnv1a hash of the memory block, described by the dynamic |
| 22 | // byte array `data`. |
| 23 | @[direct_array_access; inline] |
| 24 | pub fn sum32(data []u8) u32 { |
| 25 | mut hash := fnv32_offset_basis |
| 26 | for i in 0 .. data.len { |
| 27 | hash = (hash ^ u32(data[i])) * fnv32_prime |
| 28 | } |
| 29 | return hash |
| 30 | } |
| 31 | |
| 32 | // sum32_bytes returns a fnv1a hash of the struct `s`. |
| 33 | @[direct_array_access; inline] |
| 34 | pub fn sum32_struct[T](s &T) u32 { |
| 35 | bp := unsafe { &u8(s) } |
| 36 | sz := int(sizeof(T)) |
| 37 | mut hash := fnv32_offset_basis |
| 38 | for i in 0 .. sz { |
| 39 | hash = unsafe { (hash ^ u32(bp[i])) * fnv32_prime } |
| 40 | } |
| 41 | return hash |
| 42 | } |
| 43 | |
| 44 | // sum32_bytes returns a fnv1a hash of `data_len` bytes starting at |
| 45 | // the address in the given &byte pointer `data`. |
| 46 | @[direct_array_access; inline; unsafe] |
| 47 | pub fn sum32_bytes(data &u8, data_len int) u32 { |
| 48 | mut hash := fnv32_offset_basis |
| 49 | for i in 0 .. data_len { |
| 50 | hash = unsafe { (hash ^ u32(data[i])) * fnv32_prime } |
| 51 | } |
| 52 | return hash |
| 53 | } |
| 54 | |
| 55 | // sum64 returns a fnv1a hash of the string, described by `data` |
| 56 | @[direct_array_access; inline] |
| 57 | pub fn sum64_string(data string) u64 { |
| 58 | mut hash := fnv64_offset_basis |
| 59 | for i in 0 .. data.len { |
| 60 | hash = (hash ^ u64(data[i])) * fnv64_prime |
| 61 | } |
| 62 | return hash |
| 63 | } |
| 64 | |
| 65 | // sum64 returns a fnv1a hash of the memory block, described by the dynamic |
| 66 | // byte array `data`. |
| 67 | @[direct_array_access; inline] |
| 68 | pub fn sum64(data []u8) u64 { |
| 69 | mut hash := fnv64_offset_basis |
| 70 | for i in 0 .. data.len { |
| 71 | hash = (hash ^ u64(data[i])) * fnv64_prime |
| 72 | } |
| 73 | return hash |
| 74 | } |
| 75 | |
| 76 | // sum64_bytes returns a fnv1a hash of `data_len` bytes starting at |
| 77 | // the address in the given &byte pointer `data`. |
| 78 | @[direct_array_access; inline; unsafe] |
| 79 | pub fn sum64_bytes(data &u8, data_len int) u64 { |
| 80 | mut hash := fnv64_offset_basis |
| 81 | for i in 0 .. data_len { |
| 82 | hash = unsafe { (hash ^ u64(data[i])) * fnv64_prime } |
| 83 | } |
| 84 | return hash |
| 85 | } |
| 86 | |
| 87 | // sum64_bytes returns a fnv1a hash of the struct `s`. |
| 88 | @[direct_array_access; inline] |
| 89 | pub fn sum64_struct[T](s &T) u64 { |
| 90 | bp := unsafe { &u8(s) } |
| 91 | sz := int(sizeof(T)) |
| 92 | mut hash := fnv64_offset_basis |
| 93 | for i in 0 .. sz { |
| 94 | hash = unsafe { (hash ^ u64(bp[i])) * fnv64_prime } |
| 95 | } |
| 96 | return hash |
| 97 | } |
| 98 | |