import itertools
from math import sqrt


def is_prime(number):
    return all(number % divisor for divisor in range(2, number))


def filter_divisors(number, numbers):
    for divisor in numbers:
        if divisor % number:
            yield divisor


def primes():
    candidates = itertools.count(2)

    while True:
        prime = next(candidates)
        candidates = filter_divisors(prime, candidates)
        yield prime


def fermat_number(prime):
    if not is_prime(prime):
        raise ValueError('Number is not prime')

    return 2 ** (2 ** prime) + 1


def marsene_prime(prime):
    if not is_prime(prime):
        raise ValueError('Number is not prime')

    return 2 ** prime - 1


def gcd(a, b):
    if a % b == 0:
        return a

    return gcd(b, a % b)


def dixon_factor(number):
    base = [2, 3, 5, 7, 11, 13, 17, 19, 23]
    start = int(sqrt(number))
    pairs = []
    factors = []

    for i in range(start, number):
        for j in range(len(base)):
            lhs = i**2 % number
            rhs = base[j]**2 % number

            if lhs == rhs:
                pairs.append([i, base[j]])

    for i in range(len(pairs)):
        factor = gcd(pairs[i][0] - pairs[i][1], number)

        if(factor != 1):
            factors.append(factor)

    return factors

from math import sqrt
from random import SystemRandom


def is_prime(number):
    return all(number % divisor for divisor in range(2, number))


def filter_divisors(number, numbers):
    for divisor in numbers:
        if divisor % number:
            yield divisor


def primes():
    found = {}
    prime = 2

    while True:
        if prime not in found:
            yield prime
            found[prime * prime] = [prime]
        else:
            for p in found[prime]:
                found.setdefault(p + prime, []).append(p)

            del found[prime]

        prime += 1


def marsenne_number(number):
    return 2 ** number - 1


def is_marsenne_prime(prime):
    s = 4
    marsenne = 2 ** prime - 1

    for _ in range(prime - 2):
        s = (s ** 2 - 2) % marsenne

    return s == 0


def random_prime():
    random = SystemRandom()
    prime_generator = iter(primes())
    prime_number = next(prime_generator)

    for _ in range(random.randrange(42)):
        prime_number = next(prime_generator)

    while not is_marsenne_prime(prime_number):
        prime_number = next(prime_generator)

    return marsenne_number(prime_number)


def gcd(a, b):
    if a % b == 0:
        return a

    return gcd(b, a % b)


def factor_primes(number):
    return [factor for factor in range(2, number) if is_prime(factor)]


def dixon_factor(number):
    base = [2, 3, 5, 7, 11, 13, 17, 19, 23]
    start = int(sqrt(number))
    pairs = []
    factors = []

    for i in range(start, number):
        for j in range(len(base)):
            lhs = i**2 % number
            rhs = base[j]**2 % number

            if lhs == rhs:
                pairs.append([i, base[j]])

    for i in range(len(pairs)):
        factor = gcd(pairs[i][0] - pairs[i][1], number)

        if(factor != 1):
            factors.append(factor)

    return factors

Fix prime generator