MCPcopy Create free account
hub / github.com/TheAlgorithms/Python / pollard_rho

Function pollard_rho

maths/pollard_rho.py:6–123  ·  view source on GitHub ↗

Use Pollard's Rho algorithm to return a nontrivial factor of ``num``. The returned factor may be composite and require further factorization. If the algorithm will return None if it fails to find a factor within the specified number of attempts or within the specified number of step

(
    num: int,
    seed: int = 2,
    step: int = 1,
    attempts: int = 3,
)

Source from the content-addressed store, hash-verified

4
5
6def pollard_rho(
7 num: int,
8 seed: int = 2,
9 step: int = 1,
10 attempts: int = 3,
11) -> int | None:
12 """
13 Use Pollard's Rho algorithm to return a nontrivial factor of ``num``.
14 The returned factor may be composite and require further factorization.
15 If the algorithm will return None if it fails to find a factor within
16 the specified number of attempts or within the specified number of steps.
17 If ``num`` is prime, this algorithm is guaranteed to return None.
18 https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
19
20 >>> pollard_rho(18446744073709551617)
21 274177
22 >>> pollard_rho(97546105601219326301)
23 9876543191
24 >>> pollard_rho(100)
25 2
26 >>> pollard_rho(17)
27 >>> pollard_rho(17**3)
28 17
29 >>> pollard_rho(17**3, attempts=1)
30 >>> pollard_rho(3*5*7)
31 21
32 >>> pollard_rho(1)
33 Traceback (most recent call last):
34 ...
35 ValueError: The input value cannot be less than 2
36 """
37 # A value less than 2 can cause an infinite loop in the algorithm.
38 if num < 2:
39 raise ValueError("The input value cannot be less than 2")
40
41 # Because of the relationship between ``f(f(x))`` and ``f(x)``, this
42 # algorithm struggles to find factors that are divisible by two.
43 # As a workaround, we specifically check for two and even inputs.
44 # See: https://math.stackexchange.com/a/2856214/165820
45 if num > 2 and num % 2 == 0:
46 return 2
47
48 # Pollard's Rho algorithm requires a function that returns pseudorandom
49 # values between 0 <= X < ``num``. It doesn't need to be random in the
50 # sense that the output value is cryptographically secure or difficult
51 # to calculate, it only needs to be random in the sense that all output
52 # values should be equally likely to appear.
53 # For this reason, Pollard suggested using ``f(x) = (x**2 - 1) % num``
54 # However, the success of Pollard's algorithm isn't guaranteed and is
55 # determined in part by the initial seed and the chosen random function.
56 # To make retries easier, we will instead use ``f(x) = (x**2 + C) % num``
57 # where ``C`` is a value that we can modify between each attempt.
58 def rand_fn(value: int, step: int, modulus: int) -> int:
59 """
60 Returns a pseudorandom value modulo ``modulus`` based on the
61 input ``value`` and attempt-specific ``step`` size.
62
63 >>> rand_fn(0, 0, 0)

Callers 1

pollard_rho.pyFile · 0.85

Calls 1

rand_fnFunction · 0.85

Tested by

no test coverage detected