1use crate::globals::{DCFileHash, MAX_PRIME_NUMBERS};
23
24pub trait LegacyDCHash {
27 fn generate_hash(&self, hashgen: &mut DCHashGenerator);
29}
30
31pub struct PrimeNumberGenerator {
33 primes: Vec<u16>,
34}
35
36impl Default for PrimeNumberGenerator {
37 fn default() -> Self {
38 Self { primes: vec![2_u16] }
39 }
40}
41
42impl PrimeNumberGenerator {
43 pub fn get_prime(&mut self, n: u16) -> u16 {
47 let mut candidate: u16 = self.primes.last().unwrap() + 1_u16;
49
50 while self.primes.len() <= usize::from(n) {
51 let mut maybe_prime: bool = true;
54 let mut j: usize = 0;
55
56 while maybe_prime && self.primes.get(j).unwrap() * self.primes.get(j).unwrap() <= candidate {
57 if (self.primes.get(j).unwrap() * (candidate / self.primes.get(j).unwrap())) == candidate {
58 maybe_prime = false;
60 }
61 j += 1;
62 assert!(j < self.primes.len());
63 }
64
65 if maybe_prime {
66 self.primes.push(candidate);
67 }
68 candidate += 1;
69 }
70 *self.primes.get(usize::from(n)).unwrap()
71 }
72}
73
74#[derive(Default)]
85pub struct DCHashGenerator {
86 hash: i32,
87 index: u16,
88 primes: PrimeNumberGenerator,
89}
90
91impl DCHashGenerator {
92 pub fn add_int(&mut self, number: i32) {
94 assert!(self.index < MAX_PRIME_NUMBERS);
95
96 self.hash += i32::from(self.primes.get_prime(self.index)) * number;
97 self.index = (self.index + 1) % MAX_PRIME_NUMBERS;
98 }
99
100 pub fn add_blob(&mut self, blob: Vec<u8>) {
102 self.add_int(blob.len().try_into().unwrap());
103
104 for byte in blob.into_iter() {
105 self.add_int(i32::from(byte));
106 }
107 }
108
109 pub fn add_string(&mut self, string: String) {
111 self.add_blob(string.into_bytes());
112 }
113
114 pub const fn get_hash(&self) -> DCFileHash {
115 self.hash as u32
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::PrimeNumberGenerator;
122
123 #[test]
124 fn prime_number_generator_integrity() {
125 let mut generator: PrimeNumberGenerator = PrimeNumberGenerator::default();
126
127 let prime_numbers: Vec<u16> = vec![
128 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
129 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
130 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307,
131 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
132 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547,
133 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
134 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
135 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929,
136 ];
137
138 for (i, target_prime) in prime_numbers.into_iter().enumerate() {
139 assert_eq!(target_prime, generator.get_prime(i.try_into().unwrap()));
140 }
141 }
142}