Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append to Python list all possible transformations for each list item

Tags:

python

list

I have a list of possible passwords, and I need to append simple transformations of each password in this list. Say my list is

['sauce', 'banana']

and I have a series of transformations shown here.

'a'-->'@'

's'-->'$'

I then want to add to the list every possible transformation. So now the list should look something like

['$auce', 's@uce', '$@uce', 'b@nana', 'ban@na',
 'banan@', 'b@n@na', 'b@nan@,' 'ban@n@', 'b@n@n@']

How would I do that in Python?

I tried first creating a function that made all transformations. Then I took that transformed string and essentially did a cross product with the original string. However, this causes a lot of repeats, and it seems a bit hacky.

The function:

def symbolize(s):
    options = {
        'a': '@',
        'S': '$'
    }
    copy = ''
    for i in range(len(s)):
        if s[i] in options:
            copy += options[s[i]]
        else:
            copy += s[i]
    return copy

And then the cross product:

for x in range(len(candidates)):
    candidates += list(''.join(t) for t in itertools.product(
        *zip(candidates[x], symbolize(candidates[x]))))
like image 861
Alex Parker Avatar asked Jun 03 '26 08:06

Alex Parker


1 Answers

from itertools import product

def all_versions_of_word(word, alt_chars, skip_orig=True):
    chars = [ch + alt_chars.get(ch, "") for ch in word]
    combos = product(*chars)
    if skip_orig and word: next(combos)  # drop the first item
    return ("".join(c) for c in combos)

def transform_passwords(passwords, alt_chars={"a":"@", "s":"$"}):
    for word in passwords:
        yield from all_versions_of_word(word, alt_chars)

which runs like

>>> list(transform_passwords(['sauce', 'banana']))
['s@uce',
 '$auce',
 '$@uce',
 'banan@',
 'ban@na',
 'ban@n@',
 'b@nana',
 'b@nan@',
 'b@n@na',
 'b@n@n@']
like image 174
Hugh Bothwell Avatar answered Jun 04 '26 22:06

Hugh Bothwell