-1

I have a text string. I need to decode the text string i.e, replace every character in the string with its counterpart and then read the message. How do I achieve this?

For example:

g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.

is encoded. I need to replace a's with c, b's with d ,etc. How do I do this within Python?

There is a problem when I do replace. When I do a replace all, I replace the replaced characters and that is not what I want. I want to replace one character at a time and decode the message.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
akoppad
  • 99
  • 1
  • 3
  • 9

7 Answers7

6

Apparently string.maketrans() is the way to do it

>>> s = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
>>> from string import maketrans, ascii_lowercase
>>> T = maketrans(ascii_lowercase, ascii_lowercase[2:] + ascii_lowercase[:2])
>>> s.translate(T)
"i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that's why this text is so long. using string.maketrans() is recommended. now apply on the url."
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
1

With Python 3, it's can also look like this.

import string

message = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq   ypc " \
          "dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq " \
          "rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu " \
          "ynnjw ml rfc spj."

table = str.maketrans(string.ascii_lowercase, string.ascii_lowercase[2:] + string.ascii_lowercase[:2])

print(message.translate(table))

Use str.maketrans(x[, y[, z]]) for mapping letter "each character in x, will be mapped to the character at the same position in y." The explain is from here.

Than for substring a-z string.ascii_lowercase [2:] look here.

Community
  • 1
  • 1
Menahem
  • 41
  • 2
1

Another way..

import string

my_line = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."

table = my_line.maketrans('abcdefghijklmnopqrstuvwxyz','cdefghijklmnopqrstuvwxyzab')

print(my_line.translate(table))
Sai Kiran
  • 11
  • 1
  • Please don't post only code as an answer, but also provide an explanation of what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes – Ran Marciano Feb 11 '21 at 06:03
0

I found a way to do this without maketrans(). I did not want to depend on such a function so I made my own. Took me hours to figure it out:

def shiftAll(text, shift):
    '''
    @param text - string of text to be shifted
    @param shift - the number of times to shift all letters; int value only

    In range 'a' to 'z' and 'A' to 'Z'
    Initializes empty string newText and appends the new shifted letters to it

    To shift right on th alphabet ex: a -> b or n -> y,
    enter a positive shift ex: 1, 2, 4
    To shift left on the alphabet ex: b -> a or q -> m,
    enter a negative shift ex: -2, -1, -5

    Handles:
    Error where index out of range
    Sum of shift and position is greater than 25 or less than 0
        ~Allows cases where the letter may be 'a'(j (position) == 0)
        but the shift is negative
        ~Allows cases where the letter may be 'z'(j (position) == 25)
        but the shift is positive

    returns newText
    '''
    alpha = "abcdefghijklmnopqrstuvwxyz"

    newText = ""
    for i in text:
        if ((i not in alpha) and (i not in alpha.upper())):
            newText += i        #only replaces alphabetical characters  

        for j in range(len(alpha)):     #26 letters, so positions 0-25
            if ((i == alpha[j]) or (i == alpha[j].upper())):
                while (j + shift > 25):    #to avoid index out of range error
                    shift -= 26
                while (j + shift < 0):   #to avoid index out of range error
                    shift += 26

                if(i == alpha[j].upper()): #because letters can be capital too
                    newText += alpha[j + shift].upper()
                else:
                    newText += alpha[j + shift]

    return newText

string = input("Enter anything with letters in it: ")
aShift = int(input("Enter how many places you want to shift the letters: ") 
#let's pretend the user will actually enter an int value in aShift
result = shiftAll(string, aShift)
print(result)

This works for any string and shifts all the letters in the string by the shift. The shift must be an int.

0

Using only built ins: converting to ASCII add 2 and back to chr.

In [1]: str = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
In [2]: res = ''

In [3]: for char in str:
    tmp = char
    if tmp.isalpha():
        tmp = ord(tmp)+2
        if tmp == 123: 
            tmp = 97
        if tmp == 124:
            tmp = 98
        tmp = chr(tmp)
    res += tmp
    ....:     

In [4]: res
Out[4]: "i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that's why this text is so long. using string.maketrans() is recommended. now apply on the url."
kousha
  • 752
  • 2
  • 10
  • 23
  • you could also use based 26 and add 97 to the result, that might be a nicer solution. instead of the if statement. – kousha Aug 28 '16 at 07:18
0

a simple way to replace string on a string just using functions is:

def esta (elemento,lista):                      ##here create a function with element 
    for i in range (len(lista)):                ## in a list, and search the [i]
        if lista[i]==elemento:
            return i
    return -1

## principal program:

abc=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","a","b"]
a="g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
cad=""
cont=0
for car in a:
    if esta(car,abc)!=-1:
        cad=cad+abc[esta(car,abc)+2]
    else:
        cad=cad+car
print(cad)

if you need more explanation please contact me.

0

Look at book "Cracking Codes with Python" https://nostarch.com/crackingcodes

    # task2: http://www.pythonchallenge.com/pc/def/map.html.

    massage = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc " \
              "dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr " \
              "gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw " \
              "ml rfc spj."
    
    ALPHABET = 'abcdefghijklmnopqrstuvwxyzab'
    key = 2
    
    value = len(massage)
    new_massage = ''
    
    for num in range(0, value):
        leter = massage[num]
        try:
            index = ALPHABET.index(leter)
        except ValueError:
            new_massage = new_massage + leter
        else:
            index = index + key
            leter = ALPHABET[index]
            new_massage= new_massage + leter
        
    print(new_massage)

or for an overall solution

# task: http://www.pythonchallenge.com/pc/def/map.html.

massage = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc " \
          "dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr " \
          "gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw " \
          "ml rfc spj."

massage_1 = 'map'


class PythonChallengeTask2:
    """Class manages the resources of the script."""

    def __init__(self, massage):
        """Initialization of class resources."""
        self.ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
        self.massage = massage
        self.value_1 = len(self.massage)
        self.value_2 = len(self.ALPHABET)
        self.keys = [key for key in range(0, self.value_2)]

    def run_script(self):
        """Run the script."""
        for key in range(0, self.value_2):
            print(self._hacking_message(key))
            
    def _hacking_message(self, key):
        """Gross hacking of Caesar's cipher.
        Returns:
            str: decrypted message.
        """
        new_massage = ''
        for num in range(0, self.value_1):
            leter = self.massage[num]
            try:
                index = self.ALPHABET.index(leter)
            except ValueError:
                new_massage = new_massage + leter
            else:
                index = index + key
                if index >= self.value_2:
                    index = index - self.value_2
                leter = self.ALPHABET[index]
                new_massage= new_massage + leter
        return new_massage


if __name__ == '__main__':

    script_1 = PythonChallengeTask2(massage)
    script_1.run_script()

    script_2 = PythonChallengeTask2(massage_1)
    script_2.run_script()
    

and look closely at the result of the script.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 29 '22 at 16:53