flagsmith_flag_engine/utils/
hashing.rs1use 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}