random_icon_lib/
hashing.rs

1/// A custom hash function that is used in image generation.
2/// It works for any `String`.
3/// 
4/// # Examples
5/// 
6/// ```
7/// use random_icon_lib::hashing::hash;
8/// 
9/// let my_string = "Lorem ipsum dolor sit amet...".to_string();
10/// let my_hash = hash(my_string);
11/// assert_eq!(my_hash, 2471472878)
12/// ```
13pub fn hash(string: String) -> u32 {
14    let mut vec: Vec<u8> = string.into();
15
16    if vec.is_empty() {
17        vec = vec![0]
18    }
19    
20    //because if the string consists of many numbers
21    //then many of the values would be like 0b00000011
22    for c in vec.iter_mut() {
23        let noise = u8::try_from(c.count_zeros()).unwrap() & 0b1111;
24
25        *c = *c ^ noise;
26        *c = *c ^ (noise << 4);
27    }
28
29    let groups_of_3 = vec
30        .chunks_exact(3)
31    ;
32    let remainder = groups_of_3.remainder();
33
34    let filled_remainder = if remainder.is_empty() {
35        vec![]
36    } else {
37        let mut vec = remainder.to_vec();
38        vec.push(remainder[0].rotate_left(3));
39        if vec.len() < 3 {
40            vec.push(remainder[0].rotate_right(3));
41        }
42
43        vec![vec]
44    };
45    let filled_remainder = filled_remainder
46        .iter()
47        .map(|vec| vec.as_slice())
48    ;
49
50    let groups_of_3 = groups_of_3.chain(filled_remainder);
51
52    let large_values = groups_of_3
53        .map(|group_of_three| {
54            let arr: [u8; 3] = group_of_three.try_into().unwrap();
55            let fourth_value = bitwise_choose(arr);
56
57            let mut final_value = 0u32;
58            final_value |= u32::from(fourth_value) << 24;
59            final_value |= u32::from(arr[0]) << 16;
60            final_value |= u32::from(arr[1]) <<8;
61            final_value |= u32::from(arr[2]);
62
63            final_value
64        })
65    ;
66
67    large_values
68        .reduce(|acc, e| acc.wrapping_add(e))
69        .unwrap()
70}
71
72fn bitwise_choose(values: [u8; 3]) -> u8 {
73    (values[0] & values[1]) ^ (!values[0] & values[2])
74}