加密Cesar难以循环

时间:2015-01-01 20:33:35

标签: matlab encryption while-loop

我有一个应该在学校进行解密的程序。这是非常简单的加密风格,只应将字母移动一些步骤。例如,如果你有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)

2 个答案:

答案 0 :(得分:1)

Fellesh - 解密密文的方法似乎过于复杂,特别是考虑到Cesar Cipher用于加密(秘密)消息。由于加密只是简单地将字母x字符移动到“右”(即A到D),那么为什么不采用蛮力方法并检查所有可能的移位?由于只使用大写字母,并且字母表中只有26个字母,因此这意味着只有26个可能的移位,因此您只需几行代码即可在几秒钟内轻松获得答案。

如果您的密文短,就像您的示例一样,您可能没有足够的信息来猜测哪个字符可能是'E',或者是英语字母表中下一个最常用的字母。

答案 1 :(得分:0)

频率分析仅适用于足够大的输入。角色比字母E更丰富的机会对小文本来说变得很重要。例如,在问题1中,字母Y似乎是(明文之一)明文中最丰富的字符,由密文中的字母J表示。

因此,对于较小的文本,您只需依靠暴力和体力劳动(如果您考虑阅读25个句子的劳动力)。只需打印出25个可能的明文以及移位,然后选择一个类似于句子的明文。当然可以将句子中的单词与字典进行比较,但我怀疑这是否是预期的。