I have written a simple message encoded that encodes messages into words of 4 characters each. It generates a key that will later be used to decode the message. The key is a list of numbers. The numbers are the original whitespace positions before the encoding started.

The problem:
My program doesn't completely decode my message.

My Code:

class MessageEncoder:
    def __init__(self):
        self.key = ""


    """
        Returns the key.
        So that the user can use it if needed.
    """
    def get_key(self):
        return self.key


    """
        Generates a key from the message that will be used to encode the message.
    """
    def generate_key(self, message):
        tempkey = ""

        # Loop over the message and find the position of a space.  This position will then be part of the key.
        for index in range(len(message)):
            if message[index] == ' ':
                    tempkey += str(index) + ":"

        # Remove the trailing ':' character
        tempkey = tempkey[:len(tempkey) - 1]

        self.key = tempkey


    """
        Encode the message.
        The message will be splitted in to parts of 4 characters.
    """
    def encode(self, message):
        counter = 0
        encodedmessage = ""
        newmessage = ""

        # Generate the key before changing anyting in the message.
        self.generate_key(message)

        # Remove whitespace from the message.
        for index in range(len(message)):
            if message[index] != ' ':
                newmessage += message[index]

        for index in range(len(newmessage)):

            if counter == 4:
                encodedmessage += " " + newmessage[index]
                counter = 0
            else:
                encodedmessage += newmessage[index]

            counter += 1

        return encodedmessage

    """
        Decode the message.
        The whitespaces will be returned to their original positions.
    """
    def decode(self, message, key):
        decodedmessage = ""
        newmessage = ""
        newkey = []
        tmpline = ""
        messageindex = 0
        keyindex = 0
        keyplace = 0

        # Remove the ':' character from the key and put each number in the key into an array.
        for index in range(len(key)):
            if key[index] != ':':
                tmpline += key[index]
            else:
                newkey.append(tmpline)
                tmpline = ""

        # Remove whitespace from the message.
        for index in range(len(message)):
            if message[index] != ' ':
                newmessage += message[index]

        # Decode the message with the new key.
        keyindex = int(newkey[keyplace])
        for messageindex in range(len(newmessage)):
            if messageindex == keyindex:
                decodedmessage += " " + newmessage[messageindex]
                keyplace += 1

                if keyplace != len(newkey):
                    keyindex = int(newkey[keyplace])

            else:
                decodedmessage += newmessage[messageindex]

        return decodedmessage


if __name__ == '__main__':
    m = MessageEncoder()
    enc = m.encode("HELLO WORLD THIS IS SO COOL")
    key = m.get_key()

    dec = m.decode(enc, key)

    print("Encoded: " + enc)
    print("Decoded: " + dec)
    print("Key: " + key)

Sample output:

Encoded: HELL OWOR LDTH ISIS SOCO OL
Decoded: HELLO WORLDT HISIS SOC OOL
Key: 5:11:16:19:22

The decoded message should be: HELLO WORLD THIS IS SO COOL

You ignore spaces in the encoded message and insert a space at the appropriate number, ie. is in "key".

def decode(message, key):
    output=[]
    for ctr, ltr in enumerate(message):
        if ctr in key:
            output.append(" ")
        if ltr != " ":
            output.append(ltr)
    print "".join(output)

decode("HELLO WORLDT HISIS SOC OOL", [5, 11, 16, 19, 21])

Edited 1 Year Ago by woooee

Your keys have to be adjusted for the removed spaces ...

class MessageEncoder:
    '''change the order of spaces in a text'''

    def __init__(self):
        pass

    def get_key(self):
        '''create and return the space char index key'''
        return ':'.join(str(ix) for ix, c in enumerate(self.text) if c==' ')

    def remove_space(self):
        '''return a list of text char with space char removed'''
        return [c for c in self.text if c!=' ']

    def encode(self, text):
        '''create and return a new string with spaces every 4 characters'''
        self.text = text
        # important, create the space index key string
        self.key = self.get_key()
        new_list = []
        for ix, c in enumerate(self.remove_space()):
            if ix%4 == 0 and ix != 0:
                new_list.append(' ')
            new_list.append(c)
        new_str = ''.join(new_list)
        return new_str, self.key

    def decode(self, encoded_text, key_str):
        self.text = encoded_text
        # adjust the keys for missing/removed spaces
        key_list = [int(k)-n for n, k in enumerate(key_str.split(':'))]
        print("Adjusted index keys = {}".format(key_list))  # test
        new_list = []
        for ix, c in enumerate(self.remove_space()):
            if ix in key_list:
                new_list.append(' ')
            new_list.append(c)
        new_str = ''.join(new_list)
        return new_str


# test the module
if __name__ == '__main__':

    text = "HELLO WORLD THIS IS SO COOL"
    m = MessageEncoder()

    encoded_text, key_str = m.encode(text)
    print(key_str)
    print(encoded_text)
    print('')

    decoded = m.decode(encoded_text, key_str)
    print(decoded)

''' result ...
5:11:16:19:22
HELL OWOR LDTH ISIS SOCO OL

Adjusted index keys = [5, 10, 14, 16, 18]
HELLO WORLD THIS IS SO COOL
'''

Rewrote the code in a Python style I can understand better.

Edited 1 Year Ago by vegaseat

This question has already been answered. Start a new discussion instead.