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))