凯撒密码加密算法
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.
我的任务是编写一个函数:
- 接受两个参数:第一个是要加密的字符向量,第二个是移位量。
- returns一个输出,就是密文。
- 需要处理从 space 到
~
的所有可见 ASCII 字符(ASCII 代码 32 到 126)。如果移位后的代码超出此范围,它应该回绕。例如,如果我们将 ~
移动 1
,结果应该是 space。如果我们将 space 移动 -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
"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'
我们可以使用周期函数的思想来解决它:
周期函数在每个周期重复自身,每个周期等于 2π ...
像周期函数一样,我们有一个每 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
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.
我的任务是编写一个函数:
- 接受两个参数:第一个是要加密的字符向量,第二个是移位量。
- returns一个输出,就是密文。
- 需要处理从 space 到
~
的所有可见 ASCII 字符(ASCII 代码 32 到 126)。如果移位后的代码超出此范围,它应该回绕。例如,如果我们将~
移动1
,结果应该是 space。如果我们将 space 移动-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
"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'
我们可以使用周期函数的思想来解决它: 周期函数在每个周期重复自身,每个周期等于 2π ...
像周期函数一样,我们有一个每 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