我有一个应该在学校进行解密的程序。这是非常简单的加密风格,只应将字母移动一些步骤。例如,如果你有3个步骤,那么'A'变成'D'而'''变成'J'。他们解决这个问题的方法是通过看啊英语中最常见的字母是'E'。所以我检查文本中的常用字母并假设它们代表'E'。如果它不是最频繁的字母那么它应该是第二频率或第三等。它还使用大写字母以便于用ASCII系统识别。问题是,在我的第一篇文章中,roll不是5或10(我用第二个最常见的字母找到)但是其他东西,我找不到如何制作一个漂亮的循环,所以现在看起来真的很难看。 谢谢你的帮助
clear all;
close all;
clc;
%Opens txt file
fid=fopen('krypteradett.txt','rt');
text = fscanf(fid,'%c',Inf)
%Makes it uppercase
txtversal = upper(text);
%checks unique letters and removes unneeded spaces
bokst = unique(txtversal);
bokst = strtrim(bokst);
c = histc(txtversal, bokst);
cdescend = sort(cd,'descend');
%Prints out each unique letter and how many times they are repeated
fprintf('"%c" is %n times\n', [bokst; c])
%Finds the most frequent letter
storsta = max(max(cd));
ix=find(c==max(c));
frekvbokst = bokst(ix);
fprintf('The most frequent letter is "%cd" and can be found %d times.\n', [frekvbokst; storsta])
%Since 'E' is the most common letter in the English language, it calculates
%how many "rolls" have been made to come to the new letter. If 'G' is the
%most frequent letter in our text, then it matches how far it is from the
%letter 'E' in capital ASCII.
s = double(frekvbokst);
eiascii = double('E');
rullning = (s - eiascii);
fprintf('the roll is %d step.\n', rullning)
textascii = double(txtversal);
%Capital English letter in ASCII only range from 65 to 90, if it is out of
%range it should jump the whole alphabet (26 letters) forward/backward. And
%if it is 0, then it should become 26 to keep the spaces. Still needs
%rework as it works very bad
T = (textascii >= 65) & (textascii <= 90);
bratek(T) = (textascii(T) - rullning);
bratek(bratek < 64) = bratek(bratek < 64)+26;
bratek(bratek == 64) = bratek(bratek == 64)+26;
bratek(bratek > 90) = bratek(bratek >90)-26;
bratek(bratek == 26) = bratek(bratek == 26)-26;
char(bratek)
%Asks if the text made sense
ratt = input('Is the text reasonable? (1) for yes and (2) for no. ');
%If the text didn't make any sense, the program does the same thing as
%before just with the second most frequent letter and matches it to the
%letter 'E' to see how many rolls have been made.
if ratt == 2
nyttstorsta = max(c(c~=max(c)));
ip=find(c==nyttstorsta);
nyttfrekvbokst = bokst(ip);
nyttfrekvbokst = nyttfrekvbokst(1);
fprintf('The second most frequent letter is "%c" and can be found %d times.\n', [nyttfrekvbokst; nyttstorsta])
s = double(nyttfrekvbokst);
eiascii = double('E');
rullning = (s - eiascii);
fprintf('The roll is %d step.\n', rullning)
textascii = double(txtversal);
T = (textascii >= 65) & (textascii <= 90);
nyttbratek(T) = (textascii(T) - rullning);
nyttbratek(nyttbratek < 64) = nyttbratek(nyttbratek < 64)+26;
nyttbratek(nyttbratek == 64) = nyttbratek(nyttbratek == 64)+26;
nyttbratek(nyttbratek > 90) = nyttbratek(nyttbratek >90)-26;
nyttbratek(nyttbratek == 26) = nyttbratek(nyttbratek == 26)-26;
char(nyttbratek)
ratt = input('Is the text reasonable? (1) for yes and (2) for no. ');
elseif ratt == 1
disp('You have now decrypted the text: ')
char(bratek)
end
%Prints out diagram with most frequent letters (still needs rework as it
%doesn't print out on diagram which are the most frequent ones). It keeps
%it to the 10 most frequent ones at least.
pie(cfix)
答案 0 :(得分:1)
Fellesh - 解密密文的方法似乎过于复杂,特别是考虑到Cesar Cipher用于加密(秘密)消息。由于加密只是简单地将字母x字符移动到“右”(即A到D),那么为什么不采用蛮力方法并检查所有可能的移位?由于只使用大写字母,并且字母表中只有26个字母,因此这意味着只有26个可能的移位,因此您只需几行代码即可在几秒钟内轻松获得答案。
如果您的密文短,就像您的示例一样,您可能没有足够的信息来猜测哪个字符可能是'E',或者是英语字母表中下一个最常用的字母。
答案 1 :(得分:0)
频率分析仅适用于足够大的输入。角色比字母E
更丰富的机会对小文本来说变得很重要。例如,在问题1中,字母Y
似乎是(明文之一)明文中最丰富的字符,由密文中的字母J
表示。
因此,对于较小的文本,您只需依靠暴力和体力劳动(如果您考虑阅读25个句子的劳动力)。只需打印出25个可能的明文以及移位,然后选择一个类似于句子的明文。当然可以将句子中的单词与字典进行比较,但我怀疑这是否是预期的。