mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-23 17:38:39 +00:00
57 lines
1.6 KiB
Python
57 lines
1.6 KiB
Python
|
import math
|
|||
|
import random
|
|||
|
|
|||
|
def gcd(a, b):
|
|||
|
"""Computes the greatest common divisor using Euclidean algorithm."""
|
|||
|
while b:
|
|||
|
a, b = b, a % b
|
|||
|
return a
|
|||
|
|
|||
|
def modular_exponentiation(base, exp, mod):
|
|||
|
"""Computes (base^exp) % mod using fast modular exponentiation."""
|
|||
|
result = 1
|
|||
|
while exp > 0:
|
|||
|
if exp % 2 == 1:
|
|||
|
result = (result * base) % mod
|
|||
|
base = (base * base) % mod
|
|||
|
exp //= 2
|
|||
|
return result
|
|||
|
|
|||
|
def find_order(a, N):
|
|||
|
"""Finds the smallest r such that a^r ≡ 1 (mod N)"""
|
|||
|
r = 1
|
|||
|
while modular_exponentiation(a, r, N) != 1:
|
|||
|
r += 1
|
|||
|
if r > N: # Prevent infinite loops
|
|||
|
return None
|
|||
|
return r
|
|||
|
|
|||
|
def shor_algorithm(N):
|
|||
|
"""Simulates Shor’s Algorithm classically to factorize N."""
|
|||
|
if N % 2 == 0:
|
|||
|
return 2, N // 2 # Trivial case if N is even
|
|||
|
|
|||
|
while True:
|
|||
|
a = random.randint(2, N - 1)
|
|||
|
factor = gcd(a, N)
|
|||
|
if factor > 1:
|
|||
|
return factor, N // factor # Lucky case: a and N are not coprime
|
|||
|
|
|||
|
r = find_order(a, N)
|
|||
|
if r is None or r % 2 == 1:
|
|||
|
continue # Retry if order is not even
|
|||
|
|
|||
|
factor1 = gcd(modular_exponentiation(a, r // 2, N) - 1, N)
|
|||
|
factor2 = gcd(modular_exponentiation(a, r // 2, N) + 1, N)
|
|||
|
|
|||
|
if 1 < factor1 < N:
|
|||
|
return factor1, N // factor1
|
|||
|
if 1 < factor2 < N:
|
|||
|
return factor2, N // factor2
|
|||
|
|
|||
|
# Example usage
|
|||
|
if __name__ == "__main__":
|
|||
|
N = 15 # You can test with 21, 35, 55, etc.
|
|||
|
factors = shor_algorithm(N)
|
|||
|
print(f"Factors of {N}: {factors}")
|