凯撒密码加密算法

Caesar's cypher encryption algorithm

Caesar's cypher is the simplest encryption algorithm. It adds a fixed value to the ASCII (unicode) value of each character of a text. In other words, it shifts the characters. Decrypting a text is simply shifting it back by the same amount, that is, it substract the same value from the characters.

我的任务是编写一个函数:

这是我的 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,等等)。我应该如何更改我的代码才能做到这一点?

在你开始编写这样的代码之前,你应该牢牢掌握如何解决这个问题。

您遇到的主要障碍是如何将模运算应用于您的数据,查看 mod "wraps" 如何输入到 [0 modPeriod-1] 的范围,而您自己的数据在范围 [32 126]。为了使 mod 在这种情况下有用,我们执行一个中间步骤,将输入 移动 mod "likes" 的范围,即从一些 [minVal maxVal][0 modPeriod-1]

所以我们需要找到两件事:所需班次的大小,以及 mod 的周期大小。第一个很简单,因为这只是 -minVal,它是第一个字符的 ASCII 值的负值,即 space(在 MATLAB 中写为 ' ')。至于mod的周期,就是你的"alphabet"的大小,恰好是“移位后比最大值大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'

我们可以使用周期函数的思想来解决它: 周期函数在每个周期重复自身,每个周期等于 ...

像周期函数一样,我们有一个每 95 个值重复一次的函数

周期=126-32+1; 我们加一个,因为'32'也在循环中...

所以如果字符的值超过'126'我们减去95,

i.e. if the value =127(bigger than 126) then it is equivalent to 127-95=32 .

&如果值小于 32,我们减去 95。

i.e. if the value= 31 (less than 32) then it is equivalent to 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);

首先我将输出(shift+text_input)转换为字符。

function coded= caesar(text_input,shift)
coded=char(text_input+shift);

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

end

这是一个短代码:

function coded = caesar(v,n)
C = 32:126;
v = double(v);

for i = 1:length(v)
    x = find(C==v(i));
    C = circshift(C,-n);
    v(i) = C(x);
    C = 32:126;
end
coded = char(v);
end