Caesar的密码是最简单的加密算法。它为文本的每个字符的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等)。我应该如何更改我的代码呢?
在你开始编写这样的代码之前,你应该牢牢掌握如何解决这个问题。
您遇到的主要障碍是如何将模数运算应用于您的数据,看看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'
我们可以使用周期函数的思想来解决它:周期函数每个周期重复一次,每个周期等于2π...
像周期函数一样,我们有一个每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);