-1

I'm looking to write a piece of code in Javascript or Python that generates a wordlist file out of a pre-defined combination of characters.

E.g. input = abc output = ABC abc Abc aBc abC AbC ABc aBC

I have very basic knowledge of either so all help is appreciated.

Thank you

Nick
  • 1
  • 4
  • 1
    Does this answer your question? [How to generate all permutations of a list?](https://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list) – Ramon Moraes May 04 '20 at 20:24

2 Answers2

0

I'll assume that you're able to import Python packages. Therefore, take a look at itertools.product:

This tool computes the cartesian product of input iterables.

For example, product(A, B) returns the same as ((x,y) for x in A for y in B).

It looks quite like what you're looking for, right? That's every possible combination from two different lists.

Since you're new to Python, I'll assume you don't know what a map is. Nothing too hard to understand:

Returns a list of the results after applying the given function to each item of a given iterable (list, tuple etc.)

That's easy! So the first parameter is the function you want to apply and the second one is your iterable.

The function I applied in the map is as follows:

''.join

This way you set '' as your separator (basically no separator at all) and put together every character with .join.

Why would you want to put together the characters? Well, you'll have a list (a lot of them in fact) and you want a string, so you better put those chars together in each list.

Now here comes the hard part, the iterable inside the map:

itertools.product(*((char.upper(), char.lower()) for char in string)

First of all notice that * is the so-called splat operator in this situation. It splits the sequence into separate arguments for the function call.

Now that you know that, let's dive into the code. Your (A, B) for itertools.product(A, B) are now (char.upper(), char.lower()). That's both versions of char, upper and lowercase. And what's char? It's an auxiliar variable that will take the value of each and every character in the given string, one at a time.

Therefore for input 'abc' char will take values a, b and c while in the loop, but since you're asking for every possible combination of uppercase and lowercase char you'll get exactly what you asked for.

I hope I made everything clear enough. :)

Let me know if you need any further clarification in the comments. Here's a working function based on my previous explanation:

import itertools

def func():
    string = input("Introduce some characters: ")
    output = map(''.join, itertools.product(*((char.upper(), char.lower()) for char in string)))
    print(list(output))

As an additional note, if you printed output you wouldn't get your desired output, you have to turn the map type into a list for it to be printable.

Community
  • 1
  • 1
0

A simple approach using generators, and no library code. It returns a generator (iterator-like object), but can be converted to a list easily.

def lU(s):
    if not s:
        yield ''
    else:
        for sfx in lU(s[1:]):
            yield s[0].upper() + sfx
            yield s[0].lower() + sfx

print list(lU("abc"))

Note that all the sub-lists of suffixes are not fully expanded, but the number of generator objects (each a constant size) that get generated is proportional to the length of the string.

Amitai Irron
  • 1,973
  • 1
  • 12
  • 14
  • This works like a charm! Thank you for this. I didn't quite get this part: 'Note that all the sub-lists of suffixes are not fully expanded, but the number of generator objects (each a constant size) that get generated is proportional to the length of the string.' Anyhow it works like I wanted. – Nick May 06 '20 at 19:36
  • I'm trying to decypher this code and why it works. In the first part you say if not s. I read this as: 'if there is no input, give back an empty array. In all other cases, for sfx (no idea what sfx is) in variable lU(with parameter s) at index 1 (don't know what : here does), make s at index 0 an uppercase and add sfx? In other words, it works but I'm having a hard time understanding why. – Nick May 06 '20 at 19:53
  • So this is a recursive function based on the following premise: The result for the empty string would be a list with a single empty string in it; to get the result for a string of length N, you just need to compute the result list for the length N-1 string starting at character 1, and then create two lists - one starting with a lowercase version of the first character, and another starting with an uppercase version. Then, chain the two lists, and return them. – Amitai Irron May 06 '20 at 22:03
  • A more efficient approach, assuming your input string's length does not exceed the number of bits in the representation of an integer, would be to simply count from 0 to 2^(length)-1, and then generate a list where every binary 0 in position J would mean a lowercase letter, and every 1 an uppercase. This would be more memory- and time- efficient (no stack and no recursive calls). – Amitai Irron May 06 '20 at 22:05