简体   繁体   中英

Python, obfuscating letters in a list

I have created a list characters = list(original.lower()) to list an input of a four letter word. This breaks down the input into sepearte characters and makes them all lowercase.

In a following function I need to call each letter that was seperated and replace them with 1 of 5 set ascii chars which are ! % * # @

I have created the list into a var called - obfuscate = ["!", "%", "*", "#", "@"] and now need to but have no idea how to bring in each char and apply a random symbol to each of the letters of the input.

original = input("Enter a 4-letter word:  ")

    letters = isolate_letters(original) 
    obsfucate_letters(letters) 
    obfuscated = recompose_obfuscated_letters(letters)

    print("Original:  ", original)
    print("Obfuscated:  ", obfuscated)

def isolate_letters(original):

    characters = list(original.lower())
    print (characters)
    return characters


def obsfucate_letters(original):

    import random
    obfuscate = ["!", "%", "*", "#", "@"]
    print (random.choice(obfuscate))

EDIT:

def obfuscate_letters(word):

    import random
    new_word = ''
    for char in word:
        if random.random() < 0.9:
            new_word += random.choice(['!', '%', '&', '#', '@'])
        else:
            new_word += char
    letters = new_word
    print (letters)

def recompose_obfuscated_letters(letters):

        obfuscated = ''.join(letters)
        return obfuscated

These are my last two functions, i cannot get the letters variable returned:

this is the respons to dddd:

!@%!
Original: dddd 
Obfuscated: dddd

The top line of garble is what i need to go next to the Obfuscated bit ;/

You could make a dictionary that can map the letter to its obfuscated character

import random
def encode(word, symbols):
    obfuscate = list(symbols)
    random.shuffle(obfuscate)
    d = dict(zip(word, obfuscate))
    return ''.join(d[i] for i in word)

>>> obfuscate = ["!", "%", "*", "#", "@"]
>>> word = 'test'
>>> encode(word, obfuscate)
'#%*#'

In the encode function, the third line creates a dictionary of the following form

{'s': '*',
 't': '#',
 'e': '%'}

Since I am shuffling the list before zip ing it, the map will be randomly paired. See the following few test calls

>>> encode(word, obfuscate)
'%!#%'
>>> encode(word, obfuscate)
'@#%@'
>>> encode(word, obfuscate)
'@#*@'
>>> encode(word, obfuscate)
'%!*%'
>>> encode(word, obfuscate)
'@*%@'

If you don't need to recreate the word latter. Here's a one line solution.

import random
def obfuscate(word):
    return ''.join([random.choice(["!", "%", "*", "#", "@"]) for char in word])

Explantion:

[... for ... in ...] is a list comprehension , it generates a list of random characters using the random.choice(), then the ''.join() , concatenate all the generated characters in a single string.


EDIT:

what if the 'word' was a user input (a four letter word)?

user_input = raw_input("Enter a 4-letter word:  ")
if len(user_input) == 4:
    print obfuscate(user_input)

is there a way that there is a 10% chance of a letter in the word being left alone and not being changed?

For this the list comprehension won't work (as far as I know), but you can still do it in a for loop.

def obsfucate(word):
    new_word = ''
    for char in word:
        if random.random() > 0.1:
            new_word += random.choice(["!", "%", "*", "#", "@"])
        else:
            new_word += char
    return new_word

output:

Enter a 4-letter word:  Damn
D%*#

EDIT2:

Actually you can use list comprehensions!

def obsfucate(word):
    return ''.join([random.choice(["!", "%", "*", "#", "@"]) if random.random() > 0.1 else char for char in word])

But for me it gets a little messy.


EDIT 3:

Full code should be something like:

import random

def obfuscate(word):
    new_word = ''
    for char in word:
        if random.random() > 0.1:
            new_word += random.choice(["!", "%", "*", "#", "@"])
        else:
            new_word += char
    return new_word

user_input = raw_input("Enter a 4-letter word:  ")
if len(user_input) == 4:
    print "Original:", user_input
    print "Obfuscate:", obfuscate(user_input)

Output:

Enter a 4-letter word:  Damn
Original: Damn
Obfuscate: D@m%

If you want to use you code as it is:

import random

def isolate_letters(original):
    characters = list(original.lower())
    return characters

def obsfucate(word):
    return [random.choice(["!", "%", "*", "#", "@"]) if random.random() > 0.1 else char for char in word]

def recompose_obfuscated_letters(letters):
    obfuscated = ''.join(letters)
    return obfuscated

original = input("Enter a 4-letter word:  ")

letters = isolate_letters(original)
obsfucate_letters = obsfucate(letters)
obfuscated = recompose_obfuscated_letters(obsfucate_letters)

print("Original:", original)
print("Obfuscated:", obfuscated)

Output:

Enter a 4-letter word:  Damn
Original: Damn
Obfuscated: d!!%

This is my whole code, that you can use as is in your code excerpt.

from __future__ import print_function

def isolate_letters(s):
    return [c for c in s]

def obfuscate_letters(loc):
    from random import shuffle
    funny = ['!', '%', '*', '#', '@']
    # shuffle the list of funny characters
    shuffle(funny)
    # create a dictionary
    d = {c:f for f,c in zip(funny,set(loc))}
    # change in place the list of characters
    for i, c in enumerate(loc):
        loc[i] = d[c]

def recompose_obfuscated_letters(looc):
    return "".join(looc)

# here it is a copy and past from your OP (except for the spellung of obfuscate...)
original = 'funk'
letters = isolate_letters(original)
obfuscate_letters(letters)
obfuscated = recompose_obfuscated_letters(letters)

print('Original:    "%s"' % original)
print('Obfuscated:  "%s"' % obfuscated)

the output I have is

Original:    "funk"
Obfuscated:  "*#%@"

Key is using the shuffle function from the random module. shuffle changes at random the positions of the items in a list, so that when I access the terms in funny sequentially, I in effect access them at random...

Next issue, I find the unique characters in the input word using set() and then construct a mapping, from real characters to funny characters.

The last step is, of course, go through the original list and changing all its items one by one using the mapping that we have defined two lines above.

(this last part, modifying in place the original list, follows from how the OP coded her/his example)

A new answer because the OP has, substantially, a new question

def obfuscate_letters(s,funny=[c for c in "!!!%%%&&&###@@@  "]):
    from random import shuffle
    shuffle(funny)
    for i, c in enumerate(s):
        s[i] = funny[i] if funny[i] != ' ' else s[i]

(yes, the default argument is mutable and changes at each invocation)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM