ads2_2022/code/python/src/algorithms/pollard_rho/algorithms.py

75 lines
2.2 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.thirdparty.types import *;
from src.thirdparty.maths import *;
from models.generated.config import *;
from src.core.utils import *;
from src.models.pollard_rho import *;
from src.algorithms.pollard_rho.display import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__all__ = [
'pollard_rho_algorithm',
];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHOD pollard's rho algorithm
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def pollard_rho_algorithm(
n: int,
x_init: int = 2,
verbose: bool = False,
):
d = 1;
x = y = x_init;
steps = [];
steps.append(Step(x=x, y=y));
success = False;
f = lambda _: fct(_, n=n);
while True:
x = f(x);
y = f(f(y));
d = math.gcd(abs(x-y), n);
steps.append(Step(x=x, y=y, d=d));
if d == 1:
continue;
elif d < n:
success = True;
break;
else:
success = False;
break;
if verbose:
repr = display_table(steps=steps);
print('');
print('\x1b[1mEuklidescher Algorithmus\x1b[0m');
print('');
print(repr);
print('');
if success:
print('\x1b[1mBerechneter Faktor:\x1b[0m');
print('');
print(f'd = \x1b[1m{d}\x1b[0m.');
else:
print('\x1b[91mKein (Prim)faktor erkannt!\x1b[0m');
print('');
return d;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# AUXILIARY METHOD function for Pollard's rho
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def fct(x: int, n: int) -> int:
return (x**2 - 1) % n;