Замена буквы на "#" и обратная замена

Я новичок в python и делаю тестовую программу, которая заменяет все буквы в заданном тексте на знаки.

def encrypted(request):
    text = request.GET['text']
    
    text = text.replace("a", "#.")
    text = text.replace("b", "##.")
    text = text.replace("c", "###.")
    text = text.replace("d", "####.")
    text = text.replace("e", "#####.")
    text = text.replace("f", "######.")
    etc...

return render(request, 'encrypted.html', {'text': text})

Я добился этого, но я попробовал сделать обратный ход тем же способом, и это не сработало.

def decrypted(request):
    ftext = request.GET['text']

    ftext = ftext.replace("#.", "a")
    ftext = ftext.replace("##.", "b")
    ftext = ftext.replace("###.", "c")
    ftext = ftext.replace("####.", "d")
    ftext = ftext.replace("#####.", "e")
    etc...

    return render(request, 'decrypted.html')

Так что текст вообще не появляется на странице.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>yCrypt</title>
</head>
<body>
TEXT DECRYPTION: {{ftext}}
</body>
</html>

Интересно, почему он не показывает никаких проблем с кодом? Может быть, есть более простой способ сделать это возможным?

Не эксперт, но можно попробовать

def decrypted(request):
    ftext = request.GET['text']

    ftext = ftext.replace("#.", "a")
    ftext = ftext.replace("##.", "b")
    ftext = ftext.replace("###.", "c")
    ftext = ftext.replace("####.", "d")
    ftext = ftext.replace("#####.", "e")
    return render(request, 'decrypted.html',{'ftext':ftext})

Я не совсем понимаю, что вы пытаетесь сделать, но ваш первый вызов replace в функции decrypted найдет и заменит каждое вхождение "#." на букву "a" в каждой "зашифрованной букве", а не только в одной для "a".

Последующие вызовы replace не будут соответствовать ничему, потому что их трейлинг "#." уже был ошибочно заменен на букву "a".

Чтобы это работало так, как задумано, вы должны изменить порядок вызовов replace так, чтобы сначала находить самые длинные совпадения.

И чтобы он был отрисован, вы также должны передать его в контексте вашему шаблону рендеринга.

def decrypted(request):
    ftext = request.GET['text']

    etc...
    ftext = ftext.replace("#####.", "e")
    ftext = ftext.replace("####.", "d")
    ftext = ftext.replace("###.", "c")
    ftext = ftext.replace("##.", "b")
    ftext = ftext.replace("#.", "a")

    return render(request, 'decrypted.html', { "ftext": ftext }) 

Причина, по которой это не работает, заключается в том, что кодировка a является подстрокой b, c, d, e и т.д.

a = #.
b = ##.
c = ###.

как вы можете видеть #. находится в конце каждой закодированной строки

Итак, когда вы впервые кодируете, скажем, abc, получается #.##.###.. Когда вы выполняете шаг декодирования, используя replace("#.", "a"), вы получаете результат a#a##a, где каждый #. заменяется a и, как вы можете видеть, не остается точек.

Решение довольно простое вместо формата ###. используйте формат .###.

a = .#.
b = .##.
c = .###.

это обеспечит совпадение только правильного количества #, а не подстроки.

Итак, когда вы впервые кодируете, скажем, abc, получается .#..##..###.. Когда вы выполняете шаг декодирования, вы используете replace(".#.", "a"), вы получаете результат a.##..###., как вы можете видеть, коды для b и c все еще там.

На заметку: с помощью циклов можно сделать код намного меньше.

Имея много подобных строк кода, как у вас, и как в некоторых других ответах, вы должны рассмотреть, как вы могли бы подойти к этому алгоритмически.

Предположим, что вас интересует только кодирование строчных букв ascii. Если это так, то вы можете сделать следующее:

import string

encodemap = dict()
decodemap = dict()

for i, c in enumerate(string.ascii_lowercase, 1):
    pattern = '#' * i
    encodemap[c] = pattern + '.'
    decodemap[pattern] = c

def encode(mystring):
    return ''.join([encodemap[c] for c in mystring])

def decode(mystring):
    return ''.join([decodemap[p] for p in mystring.split('.')[:-1]])


ev = encode('helloworld')
print(ev)
dv = decode(ev)
print(dv)

Если вы хотите кодировать другие символы, то вам просто нужно изменить значение константы, используемой при построении карт кодирования и декодирования. Например, string.printable может быть хорошим выбором

Вернуться на верх