flagsmith_flag_engine/utils/
hashing.rs

1use md5::{Digest, Md5};
2use num_bigint;
3use num_traits::cast::ToPrimitive;
4
5pub fn get_hashed_percentage_for_object_ids(object_ids: Vec<&str>, iterations: u32) -> f32 {
6    let mut to_hash = object_ids.join(",");
7    let mut hasher = Md5::new();
8    for _ in 1..iterations {
9        to_hash.push_str(&object_ids.join(","))
10    }
11    hasher.update(to_hash);
12    let hash = hasher.finalize();
13    let hash_as_bigint = num_bigint::BigUint::from_bytes_be(&hash);
14    let hash_as_int = (hash_as_bigint % 9999 as u32).to_u32().unwrap();
15    let value = (hash_as_int as f32 / 9998.0) * 100.0;
16    return value;
17}
18#[cfg(test)]
19mod tests {
20    use super::*;
21    use uuid::Uuid;
22
23    #[test]
24    fn hashed_percentage_for_object_ids_is_same_for_same_ids() {
25        fn check(object_ids: Vec<&str>) {
26            let first_hashed_percetnage =
27                get_hashed_percentage_for_object_ids(object_ids.clone(), 1);
28            let second_hashed_percetnage = get_hashed_percentage_for_object_ids(object_ids, 1);
29            assert_eq!(first_hashed_percetnage, second_hashed_percetnage);
30        }
31        check(vec!["1", "2"]);
32        check(vec![&Uuid::new_v4().to_hyphenated().to_string(), "2"])
33    }
34
35    #[test]
36    fn hashed_percentage_for_object_ids_is_different_for_different_ids() {
37        let first_object_ids = vec!["1", "2"];
38        let second_object_ids = vec!["9", "10"];
39        let first_hashed_percetnage = get_hashed_percentage_for_object_ids(first_object_ids, 1);
40        let second_hashed_percetnage = get_hashed_percentage_for_object_ids(second_object_ids, 1);
41        assert!(first_hashed_percetnage != second_hashed_percetnage);
42    }
43}