Comments 4
Такая интерпретация декодирования не обрабатывает случай, когда исходный символ не найден в строке подстановки
Вообще это шифр подстановки обычный и исходя из "5WquWMKf.LMM" символ, не входящий в таблицу перекодировки, просто копируется как есть.
def decode(s: str) -> str:
subst = 'zcgXlSWkj314CwaYLvyh0U_odZH8OReKiNIr-JM2G7QAxpnmEVbqP5TuB9Ds6fFt%'
r = ''
for c in s:
p = subst.find(c)
if (p>=0):
r += subst[(p - 22) & 0x3F]
else:
r += c
return r
print(decode('5WquWMKf.LMM'))
print(decode('CP9STl-UP19poPvv'))
Можно еще развернуть таблицу:
def decode(s: str) ->str:
subst = "Q&'()*+,a./FPvq5KMhSr:;<=>?@UIT-HGylCY3DL4We0kmit8Ep9X[\\]^z`BOAgj2xf1bVnZdcoRwJ7Nsu_6Q"
r = ''
for c in s:
if c >= '%' and c <= 'z':
r += subst[ord(c)-ord('%')]
else:
r += c
return r
print(decode('5WquWMKf.LMM'))
print(decode('CP9STl-UP19poPvv'))
Ага, спасибо за код и уточнение) получается, я не ошибся, используя словосочетание "строка подстановки"
Это шифр подстановки, в котором каждому символу на входе соответствует один символ на выходе.
Реализован в форме шифра цезаря (сдвига) с перемешиванием алфавита.
Строка представляет собой случайную перестановку алфавита, "-22" это ключ цезаря (берём -22ю букву из алфавита).
Декодинг через поиск символа в строке неэффективен (O(N^2)*), для десятка строк может и пофиг, для сотен уже может быть заметно -- почему и предлагаю классическое решение здесь через конвертацию его в прямую таблицу подстановки -- декодинг в таком случае линеен к числу символов.
* да-да, я знаю что "квадрат" тут некорректно, так как subst фиксированная и мы можем представить его как просто очень дорогую константу, но уж больно легко думать в категориях "на каждый символ строки мы должны пробежаться по всей другой строке" и плевать что это разные строки -- чаще всего вторая строка сильно больше первой так что оно даже хуже квадрата по факту
Еще один пример использования IDAPy в REMA