Python bruteforce combinations with given starting line

I'm trying to make a bruteforce string generator in Python and itertools.combinations_with_replacement

it seems to only do the trick.

gen = itertools.combinations_with_replacement('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',12)
for combination in gen:
  check(''.join(combination))

      

Tell the user to run the program for hours and reach the line aaaeabdouzIU

.

Is there a way to pass the line where they left off to start making combinations from that point?

So if I pass in the string ' acc

' it should start trying ' acd

', ' ace

',...

itertools.combinations_with_replacement

doesn't foresee this initially, is there a way someone can achieve this?

+3


source to share


2 answers


Taking the source code from the itertools man page , copy the code for the combination_with_replacement code, but replace line 7 with new indices starting with the word you entered.

inputStr='acc'
indices=[pool.index(l) for l in inputStr]

      

And then run the rest of the code from the man page.



EDIT: for the complete function:

def combinations_with_replacement(iterable, r, startWord=None):
    # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC                                                                                   
    pool = tuple(iterable)
    n = len(pool)
    if not n and r:
        return
    if startWord is None:
        indices = [0] * r
    else:
        assert len(startWord) == r
        indices = [pool.index(l) for l in startWord]
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != n - 1:
                break
        else:
            return
        indices[i:] = [indices[i] + 1] * (r - i)
        yield tuple(pool[i] for i in indices)

      

+4


source


It's easy if you know, given the combination, how to create the next one.

One way to do this would be to define a mapping from combination to natural numbers and reverse mapping from natural numbers to combinations. For example you can use base62_encode

/ base62_decode

from Convert base 62

def next_comb(s):
    return base62_encode(1+base62_decode(s))

      

and a generator to generate the entire combination with a given starting point:

def generate_all(start='a'):
    while True:
        yield start
        start = next_comb(start)

      



Using:

for comb in generate_all():
    print(comb)

      

or, to resume the calculation from the starting point:

for comb in generate_all(starting_point):
    print(comb)

      

+1


source







All Articles