MahayarMir
MahayarMir

Reputation: 3

reversing this encoding algorithm in Python

I need help reversing this encoding algorithm into a decoding algorithm. I understand the swap function but I'm having trouble with rest of the code.

from string import ascii_letters, digits


def shift(text, shift: int = 0):
    SPACE = ' '
    letters = ascii_letters + digits + SPACE
    letters_length = len(letters)

    shifted_chars = []
    for char in text:
        if char in letters: 
            shifted_chars.append(letters[(letters.index(char) + shift) % letters_length])
        else:
            shifted_chars.append(char)
    return ''.join(shifted_chars)


def swap(text):
    middle = len(text) // 2
    return text[middle:] + text[:middle]

def encode(text):
    if len(text) < 2:
        return shift(text, 7)

    for i in range(31):
        text = swap(shift(text, i))

    return text

Upvotes: 0

Views: 108

Answers (1)

JosefZ
JosefZ

Reputation: 30123

Fixed owing to Parisa.H.R's useful comment(s).

The deswap(text) function equalizes asymmetric result of swap(text) in case of odd len(text).

from string import ascii_letters, digits


def shift(text, shift: int = 0):
    SPACE = ' '
    letters = ascii_letters + digits + SPACE
    letters_length = len(letters)
    shifted_chars = []
    for char in text:
        if char in letters: 
            shifted_chars.append(letters[(letters.index(char) + shift) % letters_length])
        else:
            shifted_chars.append(char)
    return ''.join(shifted_chars)


def swap(text):
    middle = len(text) // 2
    return text[middle:] + text[:middle]


def deswap(text):
    middle =  (len(text) + (len(text) % 2)) // 2
    return text[middle:] + text[:middle]


def encode(text):
    if len(text) < 2:
        return shift(text, 7)
    for i in range(31):
        text = swap(shift(text, i))
    return text


def decode(text):
    if len(text) < 2:
        return shift(text, -7)
    for i in range(30, -1, -1):
        text = deswap(shift(text, -i))
        # text = shift(deswap(text), -i)
    return text

Output:

decode(encode('opening'))   
# 'opening'
decode(encode('openin'))
# 'openin'
decode(encode('Quora'))
# 'Quora'
decode(encode('Quoran'))
# 'Quoran'
decode(encode(ascii_letters + digits)) == ascii_letters + digits
# True
decode(encode(ascii_letters + digits + ' ')) == ascii_letters + digits + ' '
# True

Upvotes: 1

Related Questions