Skip to main content
3 of 3
added 569 characters in body
RootTwo
  • 10.7k
  • 1
  • 14
  • 30

As @AustinHastings pointed out, the itertools.product solution below doesn't work right unless you start at the beginning. So here's an alternate solution:

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
    if start:
        indices = [pattern[i].index(c) for i,c in enumerate(start)]
    else:
        indices = [0]*len(pattern)
    
    while True:
        yield ''.join(pat[i] for pat,i in zip(pattern, indices))
        
        for i in range(len(indices)-1, -1, -1):
            indices[i] += 1
            if indices[i] < len(pattern[i]):
                break
            
            indices[i] = 0

mbi_gen() is a generator and can be used like so:

MBI = mbi_gen()

for n in range(10000):
    print(next(MBI))

or to generate a list of 10000 MBIs:

MBIs = list(it.islice(mbi_gen('3C12D34EF56'), 10000)

itertools.product()

This is a task made for itertools.product(). As the docs say, product(A, B, C) is equivalent to ((a,b,c) for a in A for b in B for c in C). The c cycles the fastest, then 'b' and a is the slowest. Like an odometer.

import itertools as it

DIGIT  =  '0123456789'
LETTER = 'ACDEFGHJKMNPQRTUVWXYZ'
DIGLET = DIGIT + LETTER

def mbi_gen(start=None):
    pattern = [DIGIT[1:],   # leading non-zero digit
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               DIGLET,
               DIGIT,
               LETTER,
               LETTER,
               DIGIT,
               DIGIT
              ]
                
    yield from (''.join(seq) for seq in it.product(*pattern))
RootTwo
  • 10.7k
  • 1
  • 14
  • 30