Замена буквы на "#" и обратная замена
Я новичок в 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 может быть хорошим выбором