1use std::f64;
17
18const K: [u32; 64] = [
19 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
20 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
21 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
22 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
23 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
24 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
25 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
26 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
27];
28
29fn generate_complex_random_number3(input_data: &[u8]) -> u64 {
39 let input_string = String::from_utf8_lossy(input_data);
40
41 let input_string = if input_string.chars().count() > 15 {
43 input_string.chars().take(15).collect::<String>()
44 } else {
45 input_string.to_string()
46 };
47
48 let ascii_values: Vec<u32> = input_string.chars().map(|c| c as u32).collect();
49
50 if ascii_values.is_empty() {
52 return 123456; }
54
55 let length_of_string = input_string.chars().count() as f64;
56 let sum_ascii: f64 = ascii_values.iter().map(|&x| x as f64).sum();
57 let max_ascii = *ascii_values.iter().max().unwrap() as f64;
58 let min_ascii = *ascii_values.iter().min().unwrap() as f64;
59
60 let factorial_limit = length_of_string.min(10.0) as u64;
62 let mut factorial = 1u64;
63 for i in 1..=factorial_limit {
64 factorial = factorial.saturating_mul(i); }
66
67 let sum_of_squares: f64 = ascii_values.iter().map(|&x| (x as f64).powi(2)).sum();
69
70 let result = sum_ascii.sin()
71 + length_of_string.exp()
72 + max_ascii.tan()
73 + (length_of_string + 1e-10).ln()
74 + min_ascii.abs().sqrt()
75 + factorial as f64
76 + sum_of_squares
77 - f64::atan2(length_of_string, max_ascii)
78 + length_of_string.cosh()
79 + gamma(length_of_string + 1.0);
80
81 (result.abs() as u64) % 1_000_000
82}
83fn gamma(x: f64) -> f64 {
85 if x < 0.5 {
86 std::f64::consts::PI / ((std::f64::consts::PI * x).sin() * gamma(1.0 - x))
87 } else {
88 let x = x - 1.0;
89 let p = [
90 0.99999999999980993,
91 676.5203681218851,
92 -1259.1392167224028,
93 771.32342877765313,
94 -176.61502916214059,
95 12.507343278686905,
96 -0.13857109526572012,
97 9.9843695780195716e-6,
98 1.5056327351493116e-7,
99 ];
100 let mut y = p[0];
101 for (i, &pi) in p.iter().enumerate().skip(1) {
102 y += pi / (x + i as f64);
103 }
104 let t = x + 7.5;
105 (2.0 * std::f64::consts::PI).sqrt() * t.powf(x + 0.5) * (-t).exp() * y
106 }
107}
108
109#[inline(always)]
111fn right_rotate(x: u32, amount: u32) -> u32 {
112 (x >> amount) | (x << (32 - amount))
113}
114
115fn process_chunk(mut chunk: Vec<u8>, h_values: &mut [u32; 8]) {
117 for (i, byte) in chunk.iter_mut().enumerate() {
119 if i % 2 == 0 {
120 *byte ^= 0xFF;
121 }
122 }
123
124 for byte in chunk.iter_mut() {
126 *byte = (*byte >> 5) | ((*byte << 3) & 0xFF);
127 }
128
129 let mut w = [0u32; 64];
131 for i in 0..16 {
132 w[i] = u32::from_be_bytes([
133 chunk[i * 4],
134 chunk[i * 4 + 1],
135 chunk[i * 4 + 2],
136 chunk[i * 4 + 3],
137 ]);
138 }
139
140 for i in 16..64 {
141 let s0 = right_rotate(w[i - 15], 7) ^ right_rotate(w[i - 15], 18) ^ (w[i - 15] >> 3);
142 let s1 = right_rotate(w[i - 2], 17) ^ right_rotate(w[i - 2], 19) ^ (w[i - 2] >> 10);
143 w[i] = w[i - 16]
144 .wrapping_add(s0)
145 .wrapping_add(w[i - 7])
146 .wrapping_add(s1);
147 }
148
149 let mut a = h_values[0];
151 let mut b = h_values[1];
152 let mut c = h_values[2];
153 let mut d = h_values[3];
154 let mut e = h_values[4];
155 let mut f = h_values[5];
156 let mut g = h_values[6];
157 let mut h = h_values[7];
158
159 for i in 0..64 {
161 let s1 = right_rotate(e, 6) ^ right_rotate(e, 11) ^ right_rotate(e, 25);
162 let ch = (e & f) ^ ((!e) & g);
163 let temp1 = h
164 .wrapping_add(s1)
165 .wrapping_add(ch)
166 .wrapping_add(K[i])
167 .wrapping_add(w[i]);
168 let s0 = right_rotate(a, 2) ^ right_rotate(a, 13) ^ right_rotate(a, 22);
169 let maj = (a & b) ^ (a & c) ^ (b & c);
170 let temp2 = s0.wrapping_add(maj);
171
172 h = g;
173 g = f;
174 f = e;
175 e = d.wrapping_add(temp1);
176 d = c;
177 c = b;
178 b = a;
179 a = temp1.wrapping_add(temp2);
180 }
181
182 h_values[0] = h_values[0].wrapping_add(a);
184 h_values[1] = h_values[1].wrapping_add(b);
185 h_values[2] = h_values[2].wrapping_add(c);
186 h_values[3] = h_values[3].wrapping_add(d);
187 h_values[4] = h_values[4].wrapping_add(e);
188 h_values[5] = h_values[5].wrapping_add(f);
189 h_values[6] = h_values[6].wrapping_add(g);
190 h_values[7] = h_values[7].wrapping_add(h);
191}
192
193pub fn patentmethod(message: &str) -> String {
212 let mut h_values = [
214 0x6A09E667u32,
215 0xBB67AE85,
216 0x3C6EF372,
217 0xA54FF53A,
218 0x510E527F,
219 0x9B05688C,
220 0x1F83D9AB,
221 0x5BE0CD19,
222 ];
223
224 let mut message_bytes = message.as_bytes().to_vec();
225 let original_length = (message_bytes.len() * 8) as u64;
226
227 message_bytes.push(0x80);
229
230 if message_bytes.len() == 1 {
232 message_bytes.extend_from_slice(&[0u8; 55]);
233 }
234
235 let random_value = generate_complex_random_number3(&message_bytes);
237 message_bytes.extend_from_slice(&random_value.to_be_bytes()[2..8]); while message_bytes.len() % 64 != 56 {
241 message_bytes.push(0);
242 }
243
244 message_bytes.extend_from_slice(&original_length.to_be_bytes());
246
247 for chunk_start in (0..message_bytes.len()).step_by(64) {
249 let chunk = message_bytes[chunk_start..chunk_start + 64].to_vec();
250 process_chunk(chunk, &mut h_values);
251 }
252
253 format!(
255 "{:08x}{:08x}{:08x}{:08x}{:08x}{:08x}{:08x}{:08x}",
256 h_values[0],
257 h_values[1],
258 h_values[2],
259 h_values[3],
260 h_values[4],
261 h_values[5],
262 h_values[6],
263 h_values[7]
264 )
265}
266
267#[cfg(test)]
268mod tests {
269 use super::*;
270
271 #[test]
272 fn test_basic_hash() {
273 let message = "Hello, world!";
274 let hash = patentmethod(message);
275 assert_eq!(hash.len(), 64);
276 let hash2 = patentmethod(message);
278 assert_eq!(hash, hash2);
279 }
280
281 #[test]
282 fn test_empty_string() {
283 let hash = patentmethod("");
284 assert_eq!(hash.len(), 64);
285 }
286
287 #[test]
288 fn test_long_message() {
289 let message = "anantehucnjldsnciejur380480-2=@#459mo-dlsanantehucnjldsnciejur380480-2=@#459mo-dlsgauranshi003003lavyabirthdayllllllllllanantehucnjldsnciejur380480-2=@#459mo-dlsanantehucnjldsnciejur380480-2=@#459mo-dlsgauranshi003003lavyabirthdayllllllllll";
290 let hash = patentmethod(message);
291 assert_eq!(hash.len(), 64);
292 }
293
294 #[test]
295 fn test_complex_random_number() {
296 let input = b"test";
297 let num = generate_complex_random_number3(input);
298 assert!(num < 1_000_000);
299 }
300
301 #[test]
302 fn test_different_inputs_different_hashes() {
303 let hash1 = patentmethod("test1");
304 let hash2 = patentmethod("test2");
305 assert_ne!(hash1, hash2);
306 }
307}