hash_algorithms/
lib.rs

1static M_MASK: i64 = 0x8765fed1;
2static M_SHIFT: i64 = 0;
3
4pub fn additive_hash(key: &str, prime: i64) -> i64 {
5    let bytes = key.as_bytes();
6    let mut hash: i64 = bytes.len() as i64;
7    for v in bytes {
8        hash += *v as i64;
9    }
10    return hash % prime;
11}
12
13pub fn rotating_hash(key: &str, prime: i64) -> i64 {
14    let bytes = key.as_bytes();
15    let mut hash = bytes.len() as i64;
16    for v in bytes {
17        hash = (hash << 4) ^ (hash >> 60) ^ (*v as i64);
18    }
19    return hash % prime;
20}
21
22pub fn one_by_one_hash(key: &str) -> i64 {
23    let mut hash = 0;
24    let bytes = key.as_bytes();
25    for v in bytes {
26        hash += *v as i64;
27        hash += hash << 10;
28        hash ^= hash >> 6;
29    }
30
31    hash += hash << 3;
32    hash ^= hash >> 11;
33    hash += hash << 15;
34    return hash;
35}
36
37pub fn bernstein(key: &str) -> i64 {
38    let mut hash = 0;
39    let bytes = key.as_bytes();
40    for v in bytes {
41        hash = 33 * hash + (*v as i64);
42    }
43    return hash;
44}
45
46pub fn fnv_hash(key: &str) -> i64 {
47    let mut hash: i64 = 2166136261;
48    let bytes = key.as_bytes();
49    for v in bytes {
50        hash = (hash * 16777619) ^ (*v as i64);
51    }
52    if M_SHIFT != 0 {
53        return hash;
54    }
55    return (hash ^ (hash >> M_SHIFT)) & M_MASK;
56}
57
58pub fn fnv_hash1(key: &str) -> i64 {
59    let p: i64 = 16777619;
60    let mut hash = 2166136261;
61    let bytes = key.as_bytes();
62    for v in bytes {
63        hash = (hash ^ (*v as i64)) * p;
64    }
65    hash += hash << 13;
66    hash ^= hash >> 7;
67    hash += hash << 3;
68    hash ^= hash >> 17;
69    hash += hash << 5;
70    return hash;
71}
72
73pub fn int_hash(mut key: i64) -> i64 {
74    key += !(key << 15);
75    key ^= (key >> 10);
76    key += (key << 3);
77    key ^= (key >> 6);
78    key += !(key << 11);
79    key ^= (key >> 16);
80    return key;
81}
82
83pub fn rs_hash(key: &str) -> i64 {
84    let (mut a, mut b): (i64, i64) = (63689, 378551);
85    let mut hash: i64 = 0;
86    let bytes = key.as_bytes();
87    for v in bytes {
88        hash = hash * a + (*v as i64);
89        a = (a * b) & 0x7FFFFFFF;
90    }
91    return hash & 0x7FFFFFFF;
92}
93
94pub fn js_hash(key: &str) -> i64 {
95    let mut hash = 1315423911;
96    let bytes = key.as_bytes();
97    for v in bytes {
98        hash ^= ((hash << 5) + (*v as i64) + (hash >> 2));
99    }
100    return hash & 0x7FFFFFFF;
101}
102
103pub fn pjw_hash(key: &str) -> i64 {
104    let bits_in_unsigned_int = 32;
105    let three_quarters = (bits_in_unsigned_int * 3) / 4;
106    let one_eighth = bits_in_unsigned_int / 8;
107    let high_bits = 0xFFFFFFFF << (bits_in_unsigned_int - one_eighth);
108    let mut hash = 0;
109    let mut test = 0;
110    let bytes = key.as_bytes();
111    for v in bytes {
112        hash = (hash << one_eighth) + (*v as i64);
113        test = hash & high_bits;
114        if test != 0 {
115            hash = ((hash ^ (test >> three_quarters)) & (!high_bits));
116        }
117    }
118    return hash & 0x7FFFFFFF;
119}
120
121pub fn elf_hash(key: &str) -> i64 {
122    let mut hash = 0;
123    let mut x = 0;
124    let bytes = key.as_bytes();
125    for v in bytes {
126        hash = (hash << 4) + (*v as i64);
127        x = hash & 0xF0000000;
128        if x != 0 {
129            hash ^= (x >> 24);
130            hash &= (!x);
131        }
132    }
133    return hash & 0x7FFFFFFF;
134}
135
136pub fn bkdr_hash(key: &str) -> i64 {
137    let mut hash = 0;
138    let mut seed = 131;
139    let bytes = key.as_bytes();
140    for v in bytes {
141        hash = (hash * seed) + (*v as i64);
142    }
143    return hash & 0x7FFFFFFF;
144}
145
146pub fn sdbm_hash(key: &str) -> i64 {
147    let mut hash = 0;
148    let bytes = key.as_bytes();
149    for v in bytes {
150        hash = (*v as i64) + (hash << 6) + (hash << 16) - hash;
151    }
152    return hash & 0x7FFFFFFF;
153}
154
155pub fn djb_hash(key: &str) -> i64 {
156    let mut hash = 5381;
157    let bytes = key.as_bytes();
158    for v in bytes {
159        hash = (hash << 5) + hash + (*v as i64);
160    }
161    return hash & 0x7FFFFFFF;
162}
163
164pub fn dek_hash(key: &str) -> i64 {
165    let bytes = key.as_bytes();
166    let mut hash = bytes.len() as i64;
167    for v in bytes {
168        hash = ((hash << 5) ^ (hash >> 27)) ^ (*v as i64);
169    }
170    return hash & 0x7FFFFFFF;
171}
172
173pub fn ap_hash(key: &str) -> i64 {
174    let mut hash = 0;
175    let bytes = key.as_bytes();
176    let mut step = 0;
177    for v in bytes {
178        let vv = (*v as i64);
179        if (step & 1) == 0 {
180            hash ^= ((hash << 7) ^ vv ^ (hash >> 3));
181        } else {
182            hash ^= (!((hash << 11) ^ vv ^ (hash >> 5)));
183        }
184        step += 1;
185    }
186    return hash;
187}
188
189pub fn java_hash(key: &str) -> i64 {
190    let mut hash = 0;
191    let bytes = key.as_bytes();
192    for v in bytes {
193        hash = 31 * hash + (*v as i64);
194    }
195    return hash;
196}
197
198#[cfg(test)]
199mod tests {
200    use crate::{additive_hash, rotating_hash, one_by_one_hash, bernstein, int_hash, rs_hash, js_hash, pjw_hash, elf_hash, bkdr_hash, sdbm_hash, djb_hash, dek_hash, ap_hash, java_hash};
201
202    #[test]
203    fn it_works() {
204        assert_eq!(2 + 2, 4);
205    }
206
207
208    #[test]
209    fn main() {
210        let hello = "hello";
211        println!("additive_hash {}", additive_hash(hello, 131));
212        println!("rotating_hash {}", rotating_hash(hello, 131));
213        println!("one_by_one_hash {}", one_by_one_hash(hello));
214        println!("bernstein {}", bernstein(hello));
215        println!("int_hash {}", int_hash(73));
216        // println!("{}", rs_hash(hello));
217        println!("js_hash {}", js_hash(hello));
218        println!("pjw_hash {}", pjw_hash(hello));
219        println!("elf_hash {}", elf_hash(hello));
220        println!("sdbm_hash {}", sdbm_hash(hello));
221        println!("djb_hash {}", djb_hash(hello));
222        println!("djb_hash {}", dek_hash(hello));
223        println!("ap_hash: {}", ap_hash(hello));
224        println!("java_hash {}", java_hash(hello));
225    }
226}