1

I am making a small program that guesses a password.

I am making this program just for the purpose of learning, I want to improve my python skills by making a program that have a real meaning.

for example:

using_characts = "abcdefghijklmnopqrstuvwxyz" # I have other characters in my alphabetic system

What I want to do is something like this:

for char in myCharacters:
    print(char)
    for char_1 in myCharacters:
        print(char + char_1)
        for char_2 in myCharacters:
            print(char + char_1 + char_2)
            ...etc

which makes this method non dynamic, and hard in the same time. the output should be something like this:

a

b

c

d

e

f

..etc

aa

ab

ac

..etc

ba

bb

bc

..etc
Mathew
  • 129
  • 9
  • You want to generate all the combination of all length ? – azro Jun 20 '20 at 16:38
  • 1
    Does this answer your question? [Making all possible combinations of a list](https://stackoverflow.com/questions/8371887/making-all-possible-combinations-of-a-list) – azro Jun 20 '20 at 16:39
  • Yes, and the length maybe changed later – Mathew Jun 20 '20 at 16:39
  • @azro, I haven't used itertools module before, it's for lists? I am trying to make my method work using a string, I'm not using lists in my program – Mathew Jun 20 '20 at 16:41
  • This one is useful too: [Getting all combinations of a string and its substrings](https://stackoverflow.com/questions/51538192/getting-all-combinations-of-a-string-and-its-substrings) – EdKenbers Jun 20 '20 at 16:42
  • Does this answer your question? [Getting all combinations of a string and its substrings](https://stackoverflow.com/questions/51538192/getting-all-combinations-of-a-string-and-its-substrings) – EdKenbers Jun 20 '20 at 16:43
  • @azro and it's not a good Idea to place all the possible values in the list, the possible values are nearly endless which makes the program slow using this algorithm – Mathew Jun 20 '20 at 16:43
  • no I don't want the output to be a list, I want it to be a string – Mathew Jun 20 '20 at 16:45
  • making the output a list, and then testing which value from the list are equal to correct the password (for example) will make the program 99x slower – Mathew Jun 20 '20 at 16:46
  • 1
    I've just add an answer tell me how that is ok regarding your post ;) – azro Jun 20 '20 at 16:47
  • 1
    You can use generators if you want to test possible passwords one by one and once you find the right password just stop. The key is yield keyword. :) – EdKenbers Jun 20 '20 at 16:50
  • 1
    It's like a bitcoin miner lol finding the hash :D – EdKenbers Jun 20 '20 at 17:11

4 Answers4

1

You can use itertools.product but you should really limit yourself with a small number. Generating cartesian product for higher numbers can take really long time:

from itertools import chain, product
chars = "abcdefghijklmnopqrstuvwxyz"
limit = 2
for perm in chain.from_iterable(product(chars, repeat=i) for i in range(1, limit+1)):
    print("".join(perm))
a
b
c
.
.
.
aa
ab
ac
.
.
.
zy
zz
Asocia
  • 5,935
  • 2
  • 21
  • 46
1

Here you go, this will work. Let me know if you want me to explain any part.

import itertools

using_characts = "abc"

for str_length in range(1,len(using_characts)+1):
    for q in itertools.product(using_characts,repeat=str_length):
        print("".join(q))
JimmyCarlos
  • 1,934
  • 1
  • 10
  • 24
1

So, the other answers have given you code that will probably work, but I wanted to explain a general approach. This algorithm uses a stack to keep track of the next things that need to be generated, and continues generating until it reaches the maximum length that you've specified.

from collections import deque
from typing import Deque, Iterator, Optional


def generate_next_strings(chars: str, base: str = "") -> Iterator[str]:
    # This function appends each letter of a given alphabet to the given base.
    # At its first run, it will generate all the single-length letters of the
    # alphabet, since the default base is the empty string.
    for c in chars:
        yield f"{base}{c}"


def generate_all_strings(chars: str, maxlen: Optional[int] = None) -> Iterator[str]:
    # We "seed" the stack with a generator. This generator will produce all the
    # single-length letters of the alphabet, as noted above.
    stack: Deque[Iterator[str]] = deque([generate_next_strings(chars)])

    # While there are still items (generators) in the stack...
    while stack:
        # ...pop the next one off for processing.
        next_strings: Iterator[str] = stack.popleft()

        # Take each item from the generator that we popped off,
        for string in next_strings:
            # and send it back to the caller. This is a single "result."
            yield string

            # If we're still generating strings -- that is, we haven't reached
            # our maximum length -- we add more generators to the stack for the
            # next length of strings.
            if maxlen is None or len(string) < maxlen:
                stack.append(generate_next_strings(chars, string))

You can try it using print("\n".join(generate_all_strings("abc", maxlen=5))).

asthasr
  • 9,125
  • 1
  • 29
  • 43
0

The following code will give you all combinations with lengths between 1 and max_length - 1:

import itertools

combs = []

for i in range(1, max_length):
    c = [list(x) for x in itertools.combinations(using_characts, i)]
    combs.extend(c)
izhang05
  • 744
  • 2
  • 11
  • 26