coreutils_rs/factor/
core.rs1fn mod_mul(mut a: u128, mut b: u128, m: u128) -> u128 {
8 if a.leading_zeros() + b.leading_zeros() >= 128 {
10 return (a * b) % m;
11 }
12 a %= m;
13 b %= m;
14 let mut result: u128 = 0;
15 while b > 0 {
16 if b & 1 == 1 {
17 result = result.wrapping_add(a);
18 if result >= m {
19 result -= m;
20 }
21 }
22 a <<= 1;
23 if a >= m {
24 a -= m;
25 }
26 b >>= 1;
27 }
28 result
29}
30
31fn mod_pow(mut base: u128, mut exp: u128, m: u128) -> u128 {
33 if m == 1 {
34 return 0;
35 }
36 let mut result: u128 = 1;
37 base %= m;
38 while exp > 0 {
39 if exp & 1 == 1 {
40 result = mod_mul(result, base, m);
41 }
42 exp >>= 1;
43 base = mod_mul(base, base, m);
44 }
45 result
46}
47
48fn is_prime_miller_rabin(n: u128) -> bool {
52 if n < 2 {
53 return false;
54 }
55 if n == 2 || n == 3 {
56 return true;
57 }
58 if n.is_multiple_of(2) || n.is_multiple_of(3) {
59 return false;
60 }
61
62 const SMALL_PRIMES: [u128; 15] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];
64 for &p in &SMALL_PRIMES {
65 if n == p {
66 return true;
67 }
68 if n.is_multiple_of(p) {
69 return false;
70 }
71 }
72
73 let mut d = n - 1;
75 let mut r = 0u32;
76 while d.is_multiple_of(2) {
77 d /= 2;
78 r += 1;
79 }
80
81 let witnesses: &[u128] = &[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37];
84
85 'witness: for &a in witnesses {
86 if a >= n {
87 continue;
88 }
89 let mut x = mod_pow(a, d, n);
90 if x == 1 || x == n - 1 {
91 continue;
92 }
93 for _ in 0..r - 1 {
94 x = mod_mul(x, x, n);
95 if x == n - 1 {
96 continue 'witness;
97 }
98 }
99 return false;
100 }
101 true
102}
103
104fn gcd(mut a: u128, mut b: u128) -> u128 {
106 if a == 0 {
107 return b;
108 }
109 if b == 0 {
110 return a;
111 }
112 let shift = (a | b).trailing_zeros();
113 a >>= a.trailing_zeros();
114 loop {
115 b >>= b.trailing_zeros();
116 if a > b {
117 std::mem::swap(&mut a, &mut b);
118 }
119 b -= a;
120 if b == 0 {
121 break;
122 }
123 }
124 a << shift
125}
126
127fn pollard_rho(n: u128) -> u128 {
131 if n.is_multiple_of(2) {
132 return 2;
133 }
134
135 for c_offset in 1u128..n {
136 let c = c_offset;
137 let mut x: u128 = c_offset.wrapping_mul(6364136223846793005).wrapping_add(1) % n;
138 let mut y = x;
139
140 let mut ys = x;
142 let mut q: u128 = 1;
143 let mut r: u128 = 1;
144 let mut d: u128 = 1;
145
146 while d == 1 {
147 x = y;
148 for _ in 0..r {
149 y = mod_mul(y, y, n).wrapping_add(c) % n;
150 }
151 let mut k: u128 = 0;
152 while k < r && d == 1 {
153 ys = y;
154 let m = (r - k).min(128);
155 for _ in 0..m {
156 y = mod_mul(y, y, n).wrapping_add(c) % n;
157 q = mod_mul(q, x.abs_diff(y), n);
158 }
159 d = gcd(q, n);
160 k += m;
161 }
162 r *= 2;
163 }
164
165 if d == n {
166 loop {
168 ys = mod_mul(ys, ys, n).wrapping_add(c) % n;
169 d = gcd(x.abs_diff(ys), n);
170 if d > 1 {
171 break;
172 }
173 }
174 }
175
176 if d != n {
177 return d;
178 }
179 }
180 n
181}
182
183fn factor_recursive(n: u128, factors: &mut Vec<u128>) {
185 if n <= 1 {
186 return;
187 }
188 if is_prime_miller_rabin(n) {
189 factors.push(n);
190 return;
191 }
192
193 let mut d = pollard_rho(n);
195 if d == n {
197 d = 2;
199 while d * d <= n {
200 if n.is_multiple_of(d) {
201 break;
202 }
203 d += 1;
204 }
205 if d * d > n {
206 factors.push(n);
208 return;
209 }
210 }
211 factor_recursive(d, factors);
212 factor_recursive(n / d, factors);
213}
214
215pub fn factorize(n: u128) -> Vec<u128> {
220 if n <= 1 {
221 return vec![];
222 }
223
224 let mut factors = Vec::new();
225 let mut n = n;
226
227 const SMALL_PRIMES: [u128; 15] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];
229 for &p in &SMALL_PRIMES {
230 while n.is_multiple_of(p) {
231 factors.push(p);
232 n /= p;
233 }
234 }
235
236 let mut i: u128 = 53;
238 while i * i <= n && i < 10000 {
239 while n.is_multiple_of(i) {
240 factors.push(i);
241 n /= i;
242 }
243 i += 2;
244 while n.is_multiple_of(i) {
245 factors.push(i);
246 n /= i;
247 }
248 i += 4;
249 }
250
251 if n > 1 {
253 factor_recursive(n, &mut factors);
254 factors.sort();
255 }
256
257 factors
258}
259
260pub fn format_factors(n: u128) -> String {
263 let factors = factorize(n);
264 let mut result = String::with_capacity(64);
266 if n <= u64::MAX as u128 {
268 let mut buf = itoa::Buffer::new();
269 result.push_str(buf.format(n as u64));
270 } else {
271 use std::fmt::Write;
272 let _ = write!(result, "{}", n);
273 }
274 result.push(':');
275 for f in &factors {
276 result.push(' ');
277 if *f <= u64::MAX as u128 {
278 let mut buf = itoa::Buffer::new();
279 result.push_str(buf.format(*f as u64));
280 } else {
281 use std::fmt::Write;
282 let _ = write!(result, "{}", f);
283 }
284 }
285 result
286}