px_native/cipher/
offsets.rs1use crate::cipher::b64::h_p;
8use crate::cipher::remap::v_m;
9use crate::cipher::xor::{VJ, jw};
10
11pub fn v_n(target_len: usize, len_bound: usize, secret: &[u8]) -> Vec<i64> {
12 let a_f = jw(h_p(secret).as_bytes(), VJ);
13 if a_f.is_empty() {
14 return Vec::new();
15 }
16 let len_bound_i = len_bound as i64;
17 let a_h = max_product(&a_f, target_len);
18 let mut a_g: Vec<i64> = Vec::with_capacity(target_len);
19 for a_m in 0..target_len {
20 let a_n = (a_m / a_f.len()) + 1;
21 let a_o = a_m % a_f.len();
22 let mut a_p = i64::from(a_f[a_o]) * i64::from(a_f[a_n]);
23 if a_p >= len_bound_i {
24 a_p = v_m(a_p, 0, a_h, 0, len_bound_i - 1);
25 }
26 while a_g.contains(&a_p) {
27 a_p += 1;
28 }
29 a_g.push(a_p);
30 }
31 a_g.sort_unstable();
32 a_g
33}
34
35fn max_product(a_f: &[u8], target_len: usize) -> i64 {
36 let mut a_h: i64 = -1;
37 for a_i in 0..target_len {
38 let a_j = ((a_i as f64) / (a_f.len() as f64) + 1.0).floor() as usize;
41 let a_k = if a_i >= a_f.len() {
42 a_i % a_f.len()
43 } else {
44 a_i
45 };
46 let a_l = i64::from(a_f[a_k]) * i64::from(a_f[a_j]);
47 if a_l > a_h {
48 a_h = a_l;
49 }
50 }
51 a_h
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn output_is_sorted_and_sized() {
60 let offsets = v_n(50, 50, b"some-secret");
61 assert_eq!(offsets.len(), 50);
62 for w in offsets.windows(2) {
63 assert!(w[0] <= w[1]);
64 }
65 }
66
67 #[test]
68 fn empty_secret_returns_empty() {
69 assert!(v_n(10, 10, b"").is_empty());
70 }
71}