def primefac(n, trial_limit=1000, rho_rounds=42000, verbose=False,
             methods=(_primefac.pollardRho_brent, _primefac.pollard_pm1, _primefac.williams_pp1, _primefac.ecm, _primefac.mpqs,
                      _primefac.fermat, _primefac.factordb), timeout=60):
    from _primefac import isprime, isqrt, primegen
    from six.moves import xrange, reduce
    from random import randrange
    import six
    timeout = timeout - 1
    if n < 2:
        return
    if isprime(n):
        yield n
        return

    factors, nroot = [], isqrt(n)
    # Note that we remove factors of 2 whether the user wants to or not.
    for p in primegen():
        if n % p == 0:
            while n % p == 0:
                yield p
                n //= p
            nroot = isqrt(n)
            if isprime(n):
                yield n
                return
        if p > nroot:
            if n != 1:
                yield n
            return
        if p >= trial_limit:
            break
    if isprime(n):
        yield n
        return

    if rho_rounds == "inf":
        factors = [n]
        while len(factors) != 0:
            n = min(factors)
            factors.remove(n)
            f = _primefac.pollardRho_brent(n)
            if isprime(f):
                yield f
            else:
                factors.append(f)
            n //= f
            if isprime(n):
                yield n
            else:
                factors.append(n)
        return

    factors, difficult = [n], []
    while len(factors) != 0:
        rhocount = 0
        n = factors.pop()
        try:
            g = n
            while g == n:
                x, c, g = randrange(1, n), randrange(1, n), 1
                y = x
                while g == 1:
                    if rhocount >= rho_rounds:
                        raise Exception
                    rhocount += 1
                    x = (x**2 + c) % n
                    y = (y**2 + c) % n
                    y = (y**2 + c) % n
                    g = gcd(x-y, n)
            # We now have a nontrivial factor g of n.  If we took too long to get here, we're actually at the except statement.
            if isprime(g):
                yield g
            else:
                factors.append(g)
            n //= g
            if isprime(n):
                yield n
            else:
                factors.append(n)
        except Exception:
            difficult.append(n)  # Factoring n took too long.  We'll have multifactor chug on it.

    factors = difficult
    while len(factors) != 0:
        n = min(factors)
        factors.remove(n)
        f = multifactor(n, methods=methods, verbose=verbose, timeout=timeout)
        if isprime(f):
            yield f
        else:
            factors.append(f)
        n //= f
        if isprime(n):
            yield n
        else:
            factors.append(n)
Beispiel #2
0
def primefac(n,
             trial_limit=1000,
             rho_rounds=42000,
             verbose=False,
             methods=factoring_methods.values()):
    from random import randrange
    if n < 2:
        return
    if _primefac.isprime(n):
        yield n
        return

    factors, nroot = [], _primefac.isqrt(n)
    # Note that we remove factors of 2 whether the user wants to or not.
    for p in _primefac.primegen():
        if n % p == 0:
            while n % p == 0:
                yield p
                n //= p
            nroot = _primefac.isqrt(n)
            if _primefac.isprime(n):
                yield n
                return
        if p > nroot:
            if n != 1:
                yield n
            return
        if p >= trial_limit:
            break
    if _primefac.isprime(n):
        yield n
        return

    if rho_rounds == "inf":
        factors = [n]
        while len(factors) != 0:
            n = min(factors)
            factors.remove(n)
            f = _primefac.pollardRho_brent(n)
            if _primefac.isprime(f):
                yield f
            else:
                factors.append(f)
            n //= f
            if _primefac.isprime(n):
                yield n
            else:
                factors.append(n)
        return

    factors, difficult = [n], []
    while len(factors) != 0:
        rhocount = 0
        n = factors.pop()
        try:
            g = n
            while g == n:
                x, c, g = randrange(1, n), randrange(1, n), 1
                y = x
                while g == 1:
                    if rhocount >= rho_rounds:
                        raise Exception
                    rhocount += 1
                    x = (x**2 + c) % n
                    y = (y**2 + c) % n
                    y = (y**2 + c) % n
                    g = _primefac.gcd(x - y, n)
            # We now have a nontrivial factor g of n.  If we took too long to
            # get here, we're actually at the except statement.
            if _primefac.isprime(g):
                yield g
            else:
                factors.append(g)
            n //= g
            if _primefac.isprime(n):
                yield n
            else:
                factors.append(n)
        except Exception:
            # Factoring n took too long.  We'll have multifactor chug on it.
            difficult.append(n)

    factors = difficult
    while len(factors) != 0:
        n = min(factors)
        factors.remove(n)
        f = multifactor(n, methods=methods, verbose=verbose)
        if _primefac.isprime(f):
            yield f
        else:
            factors.append(f)
        n //= f
        if _primefac.isprime(n):
            yield n
        else:
            factors.append(n)