Алгоритм шифрования Цезаря - PullRequest
0 голосов
/ 18 марта 2019

Шифр ​​Цезаря - самый простой алгоритм шифрования.Это добавляет фиксированное значение к значению ASCII (Unicode) каждого символа текста.Другими словами, это меняет персонажей.Расшифровка текста просто сдвигает его обратно на ту же величину, то есть вычитает одинаковое значение из символов.

Моя задача - написать функцию, которая:

  • принимает два аргумента: первый - это символьный вектор, который необходимо зашифровать, а второй - величина сдвига.
  • возвращает один вывод, который является зашифрованным текстом.
  • должен работать со всеми видимыми символами ASCII от пробела до ~ (коды ASCII от 32 до 126).Если сдвинутый код выходит за пределы этого диапазона, он должен обернуться.Например, если мы сместим ~ на 1, результатом должен быть пробел.Если мы сместим пробел на -1, результат будет ~.

Это мой код MATLAB:

function [coded] = caesar(input_text, shift)
x = double(input_text); %converts char symbols to double format
for ii = 1:length(x) %go through each element
    if (x(ii) + shift > 126) & (mod(x(ii) + shift, 127) < 32)
        x(ii) = mod(x(ii) + shift, 127) + 32; %if the symbol + shift > 126, I make it 32
    elseif (x(ii) + shift > 126) & (mod(x(ii) + shift, 127) >= 32)
        x(ii) = mod(x(ii) + shift, 127);
    elseif (x(ii) + shift < 32) & (126 + (x(ii) + shift - 32 + 1) >= 32)
        x(ii) = 126 + (x(ii) + shift - 32 + 1);
    elseif (x(ii) + shift < 32) & (126 + (x(ii) + shift - 32 + 1) < 32)
        x(ii) = abs(x(ii) - 32 + shift - 32);
    else x(ii) = x(ii) + shift;
    end
end
     coded = char(x); % converts double format back to char
end

Кажется, я не могу сделать переносправильные преобразования (например, от 31 до 126, от 30 до 125, от 127 до 32 и т. д.).Как мне изменить свой код, чтобы сделать это?

Ответы [ 2 ]

2 голосов
/ 18 марта 2019

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

Основное препятствие, с которым вы столкнулись, - это как применить операцию модуля к вашим данным, видя, как 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'
0 голосов
/ 05 июня 2019

Мы можем решить это, используя идею периодических функций: периодическая функция повторяется каждый цикл, и каждый цикл равен ...

как периодические функции, у нас есть функция, которая повторяется каждые 95 значений

цикл = 126-32 + 1; мы добавляем один, потому что '32' также находится в цикле ...

Поэтому, если значение символа превышает '126' , мы вычитаем 95,

т.е. если значение = 127 ( больше, чем 126 ), то оно эквивалентно 127-95 = 32.

& если значение меньше 32, мы вычитаем 95.

т.е.. если значение = 31 ( меньше 32 ), то оно равно 31 + 95 = 126 ..

Теперь мы переведем это в коды:

function out= caesar(string,shift)
value=string+shift;

for i=1:length(value)
    while value(i)<32
        value(i)=value(i)+95;
    end
    while value(i)>126 
        value(i)=value(i)-95;
    end

end
out=char(value);
...