oxihuman_core/
string_hash.rs1#![allow(dead_code)]
2#[allow(dead_code)]
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct StringHash(pub u64);
9
10#[allow(dead_code)]
11pub fn compute_string_hash(s: &str) -> StringHash {
12 StringHash(string_hash_u64(s))
13}
14
15#[allow(dead_code)]
16pub fn string_hash_u32(s: &str) -> u32 {
17 let mut h: u32 = 5381;
18 for b in s.bytes() {
19 h = h.wrapping_mul(33).wrapping_add(u32::from(b));
20 }
21 h
22}
23
24#[allow(dead_code)]
25pub fn string_hash_u64(s: &str) -> u64 {
26 let mut h: u64 = 14_695_981_039_346_656_037;
27 for b in s.bytes() {
28 h ^= u64::from(b);
29 h = h.wrapping_mul(1_099_511_628_211);
30 }
31 h
32}
33
34#[allow(dead_code)]
35pub fn string_hashes_equal(a: &str, b: &str) -> bool {
36 string_hash_u64(a) == string_hash_u64(b)
37}
38
39#[allow(dead_code)]
40pub fn hash_combine_strings(a: &str, b: &str) -> u64 {
41 let ha = string_hash_u64(a);
42 let hb = string_hash_u64(b);
43 ha ^ (hb
44 .wrapping_add(0x9e37_79b9_7f4a_7c15)
45 .wrapping_add(ha << 6)
46 .wrapping_add(ha >> 2))
47}
48
49#[allow(dead_code)]
50pub fn hash_to_hex_sh(hash: u64) -> String {
51 format!("{:016x}", hash)
52}
53
54#[allow(dead_code)]
55pub fn string_hash_seed(s: &str, seed: u64) -> u64 {
56 let mut h = seed;
57 for b in s.bytes() {
58 h ^= u64::from(b);
59 h = h.wrapping_mul(1_099_511_628_211);
60 }
61 h
62}
63
64#[allow(dead_code)]
65pub fn hash_empty_string() -> u64 {
66 string_hash_u64("")
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_compute_string_hash() {
75 let h = compute_string_hash("hello");
76 assert_ne!(h.0, 0);
77 }
78
79 #[test]
80 fn test_string_hash_u32() {
81 let h = string_hash_u32("test");
82 assert_ne!(h, 0);
83 }
84
85 #[test]
86 fn test_string_hash_u64() {
87 let h = string_hash_u64("test");
88 assert_ne!(h, 0);
89 }
90
91 #[test]
92 fn test_string_hashes_equal() {
93 assert!(string_hashes_equal("abc", "abc"));
94 assert!(!string_hashes_equal("abc", "def"));
95 }
96
97 #[test]
98 fn test_hash_combine_strings() {
99 let h = hash_combine_strings("hello", "world");
100 assert_ne!(h, string_hash_u64("hello"));
101 }
102
103 #[test]
104 fn test_hash_to_hex_sh() {
105 let hex = hash_to_hex_sh(255);
106 assert_eq!(hex, "00000000000000ff");
107 }
108
109 #[test]
110 fn test_string_hash_seed() {
111 let h1 = string_hash_seed("test", 42);
112 let h2 = string_hash_seed("test", 99);
113 assert_ne!(h1, h2);
114 }
115
116 #[test]
117 fn test_hash_empty_string() {
118 let h = hash_empty_string();
119 assert_eq!(h, string_hash_u64(""));
120 }
121
122 #[test]
123 fn test_deterministic() {
124 assert_eq!(string_hash_u64("abc"), string_hash_u64("abc"));
125 }
126
127 #[test]
128 fn test_different_strings() {
129 assert_ne!(string_hash_u64("abc"), string_hash_u64("xyz"));
130 }
131}