Прежде чем вы начнете кодировать что-то вроде этого, вы должны иметь четкое представление о том, как подходить к проблеме.
Основное препятствие, с которым вы столкнулись, - это как применить операцию модуля к вашим данным, видя, как mod
«оборачивает» входные данные в диапазон [0 modPeriod-1]
, в то время как ваши собственные данные находятся в диапазоне [32 126]
.Чтобы сделать mod
полезным в этом случае, мы выполняем промежуточный шаг , смещая входа в диапазон, который mod
"любит", то есть от некоторого [minVal maxVal]
до [0 modPeriod-1]
.
Итак, нам нужно найти две вещи: размер требуемого сдвига и размер периода mod
.Первый простой, поскольку это просто -minVal
, что является отрицательным значением ASCII первого символа, который является пробелом (записывается как ' '
в MATLAB).Что касается периода mod
, это просто размер вашего «алфавита», который оказывается «на 1 больше максимального значения после сдвига», или другими словами - maxVal-minVal+1
.По сути, мы делаем следующее:
input -> shift to 0-based ("mod") domain -> apply mod() -> shift back -> output
Теперь посмотрим, как это можно написать, используя векторизованную запись MATLAB:
function [coded] = caesar(input_text, shift)
FIRST_PRINTABLE = ' ';
LAST_PRINTABLE = '~';
N_PRINTABLE_CHARS = LAST_PRINTABLE - FIRST_PRINTABLE + 1;
coded = char(mod(input_text - FIRST_PRINTABLE + shift, N_PRINTABLE_CHARS) + FIRST_PRINTABLE);
Вот несколько тестов:
>> caesar('blabla', 1)
ans =
'cmbcmb'
>> caesar('cmbcmb', -1)
ans =
'blabla'
>> caesar('blabla', 1000)
ans =
'5?45?4'
>> caesar('5?45?4', -1000)
ans =
'blabla'