# [Tutor] All possible 16 character alphanumeric strings?

Steven D'Aprano steve at pearwood.info
Sun Sep 16 06:10:29 CEST 2012

```On 16/09/12 13:48, akleider at sonic.net wrote:

> What interests me, and I acknowledge that this is more a question for a
> computer science forum than a python one, is: can this be done in a non
> recursive way so the limiting factor will be time, not memory?  I couldn't
> think of a way.

Of course. That's what iterators and generators are for: to generate data
lazily, as required, rather than all up front.

Since this project isn't homework and I have no fear that I'm going to teach
the US and Chinese governments how to break the TOR network's security
module, here's how you could do it given enough time.

py> import string, itertools
py> chars = '234567' + string.lowercase
py> chars
'234567abcdefghijklmnopqrstuvwxyz'
py> it = itertools.product(*([chars]*16))
py> next(it)
('2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2')
py> for i in range(5):  # get the next five address
...     print(''.join(next(it)) + '.onion')
...
2222222222222223.onion
2222222222222224.onion
2222222222222225.onion
2222222222222226.onion
2222222222222227.onion

py> # grab 10 thousand addresses
... addresses = list(itertools.islice(it, 10000))
py> [''.join(a)+'.onion' for a in addresses[-3:]]  # look at the last three
['2222222222222dsn.onion', '2222222222222dso.onion', '2222222222222dsp.onion']

py> # skip ahead a million addresses, just throwing the values away
... for i in range(1000000):
...     _ = next(it)
...
py> ''.join(next(it))
'222222222222yueq'

Like the speedo on your car, each digit takes longer and longer to roll over
as you move towards the left. It took < ten thousand iterations to change the
third digit from the right. It took < a million iterations to change the
fourth digit. To roll over the left-most 2 into a 3 will take 32**15 iterations,
or 37778931862957161709568.

--
Steven
```