def main(argv):
    from six.moves import xrange, reduce
    import six
    if len(argv) == 1:
        sysexit(usage)
    rpx, tr, rr, veb, su = [], 1000, 42000, False, False
    ms = {"prb": _primefac.pollardRho_brent,
          "p-1": _primefac.pollard_pm1,
          "p+1": _primefac.williams_pp1,
          "ecm": _primefac.ecm,
          "mpqs": _primefac.mpqs,
          "fermat": _primefac.fermat,
          "factordb": _primefac.factordb}
    methods = (_primefac.pollardRho_brent, _primefac.pollard_pm1, _primefac.williams_pp1, _primefac.ecm, _primefac.mpqs, _primefac.fermat, _primefac.factordb)
    try:
        for arg in argv[1:]:
            if arg in ("-v", "--verbose"):
                veb = True
            elif arg in ("-s", "--summary"):
                su = True
            elif arg in ("-vs", "-sv"):
                veb, su = True, True
            elif arg[:3] == "-t=":
                tr = "inf" if arg[3:] == "inf" else int(arg[3:])    # Maximum number for trial division
            elif arg[:3] == "-r=":
                rr = "inf" if arg[3:] == "inf" else int(arg[3:])    # Number of rho rounds before multifactor
            elif arg[:3] == "-m=":  # methods = tuple(ms[x] for x in arg[3:].split(',') if x in ms)
                methods = []
                for x in arg[3:].split(','):
                    if x in ms:
                        if x in ("p-1", "p+1", "mpqs") and ms[x] in methods:
                            continue
                        methods.append(ms[x])
            else:
                rpx.append(arg)
        nums = rpn(' '.join(rpx))
    except:
        sysexit("Error while parsing arguments" + str(e))
    if su:
        print()
    for n in nums:
        print("%d: " % n, end='')
        f = {}
        for p in primefac(n, trial_limit=(n if tr == "inf" else tr),
                            rho_rounds=rr, verbose=veb, methods=methods):
            f[p] = f.get(p, 0) + 1
            print(p, end=' ')
            stdout.flush()
            assert _primefac.isprime(p) and n % p == 0, (n, p)
        print()
        if su:
            print("Z%d  = " % len(str(n)), end='')
            outstr = ""
            for p in sorted(f):
                if f[p] == 1:
                    outstr += "P%d x " % len(str(p))
                else:
                    outstr += "P%d^%d x " % (len(str(p)), f[p])
            outstr = outstr[:-2] + " = "
            for p in sorted(f):
                if f[p] == 1:
                    outstr += " %d x" % p
                else:
                    outstr += " %d^%d x" % (p, f[p])
            print(outstr[:-2])
            print()
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)
示例#3
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)