破解凯撒密码(离散数学)

首先来看以下恺撒密码。

离散数学的一道作业题。

凯撒密码作为一种最为古老的对称加密体制,在古罗马的时候都已经很流行,他的基本思想是:通过把字母移动一定的位数来实现加密和解密。例如,如果密匙是把明文字母的位数向后移动三位,那么明文字母B就变成了密文的E,依次类推,X将变成A,Y变成B,Z变成C,由此可见,位数就是凯撒密码加密和解密的密钥。

题目如下:

It is known that the following crypted paragraph is encryted using a slighted enhanced Caesar encryption method of the form f(p)=(ap+b)mod29.

jgc!.chr, dhdw,nbn bn kdncy oh uxc jdru uxdul bh dh, qbfch nugcurx oj mgbuuch wdhq.dqcl rcgudbh wcuucgn dhy roakbhdubohn oj wcuucgn orr.g mbuxfdg,bhq jgc!.chrbcns aogcofcgl uxcgc bn d rxdgdrubnubr ybnugbk.uboh oj wcuucgn uxdu bn go.qxw, uxc ndac jog dwaonu dww ndavwcn oj uxdu wdhq.dqcs

What is also known is the two most frequently used letters in the paragraph are t and e.The reference alphabet is an array of length 29 "abcdefghijklmnopqrstuvwxyz,.!", indicating that space is not handled during encryption (space remains space). Try to de-cypher the message and give the plaintext.


简单理解就是解密一段文字,加密方式为f(p)=(ap+b)mod29的凯撒加密方式,算是恺撒密码的加强版。字母表为"abcdefghijklmnopqrstuvwxyz,.!",且根据统计,t和e为英语中出现最多的字母。

破解的一般思路就是通过字母的频率求得对应的密钥,然后反解密文。求解过程如下。



统计字母出现

[cpp]  view plain copy
  1. void analyze(char *c)  
  2. {  
  3.     int a[26]={0};  
  4.     int i=0,j;  
  5.     while(c[i]!='\0')  
  6.     {  
  7.         if(c[i]!='.'||c[i]!='!'||c[i]!=',')  
  8.         a[c[i]-'a']++;  
  9.         printf("%d\t",i++);  
  10.     }  
  11.     for(j=0;j<26;j++)  
  12.     {  
  13.           
  14.         printf("%c:%d\n",j+'a',a[j]);  
  15.     }  
  16.       
  17. }  

在main中调用。

[cpp]  view plain copy
  1. int main()  
  2. {  
  3.     char ch1[10000];  
  4.     char hash[29];  
  5.       
  6.     printf("Input paragragh:\n");  
  7.     gets(ch1);  
  8.     analyze(ch1);  
  9.     return 1;  
  10. }  

得到结果:


可治u和c为出现频率最高的两个字母。

在字母表中的顺序:

t-19 u-20 e-4 c-2

可以列出下面的式子:

(19a+b)mod29=20

(4a+b)mod29=2

但是还不能求得a和b的值,需要用一段程序枚举求得。

[cpp]  view plain copy
  1. #include<stdio.h>  
  2. void getA()  
  3. {  
  4.     int a,b;  
  5.     for(a=0;a<20;a++)  
  6.     {  
  7.         b=20-(19*a)%29;  
  8.         if((4*a+b)%29==2)  
  9.         printf("%d,%d\n",a,b);  
  10.     }  
  11. }  
  12. int main()  
  13. {  
  14.     getA();  
  15.     return 1;  
  16. }  



得到a=7,b=3.


由于f(p)是满足双射关系的,即两两对应,可以将明暗文对应关系放在Hash表中。

[cpp]  view plain copy
  1. char alphabet[]="abcdefghijklmnopqrstuvwxyz,.!";  
  2. void createHash(char *c,int a,int b,int d)  
  3. {  
  4.     int i;  
  5.     char encode[29];  
  6.     for(i=0;i<29;i++)  
  7.     {  
  8.         encode[i]=alphabet[(a*i+b)%d];  
  9.         printf("%c",encode[i]);  
  10.     }  
  11.     for(i=0;i<29;i++)  
  12.     {  
  13.         c[encode[i]-'a']=alphabet[i];  
  14.     }  
  15. }  

这样就可以通过密文直接hash到明文了。

解密函数就最简单了。

[cpp]  view plain copy
  1. void decypher(char *c,char *hashmap,int a,int b,int d)  
  2. {  
  3.     int i=0;  
  4.     int char_pos;//record the caractor's position  
  5.     while(c[i]!='\0')  
  6.     {  
  7.         char_pos=c[i]-'a';  
  8.         //printf("char_pos:%d\n",char_pos);  
  9.         if(c[i]!=' ')  
  10.         {  
  11.             printf("%c",hashmap[char_pos]);  
  12.         }  
  13.         else  
  14.         {  
  15.             printf(" ");  
  16.         }  
  17.         i++;  
  18.     }  
  19. }  


完整的程序如下:

[cpp]  view plain copy
  1. #include<stdio.h>  
  2. void analyze(char *c);  
  3. void decypher(char *c,char *hashmap,int a,int b,int d);  
  4. void createHash(char *c,int a,int b,int d);  
  5. char alphabet[]="abcdefghijklmnopqrstuvwxyz,.!";  
  6. int main()  
  7. {  
  8.     char ch1[10000];  
  9.     char hash[29];  
  10.       
  11.     printf("Input paragragh:\n");  
  12.     gets(ch1);  
  13.     analyze(ch1);  
  14.     printf("\nAfter decyphered:\n");  
  15.     createHash(hash,7,3,29);  
  16.     decypher(ch1,hash,7,3,29);  
  17.       
  18.     printf("\n%s\n",ch1);  
  19.     return 1;  
  20. }  
  21. void analyze(char *c)  
  22. {  
  23.     int a[26]={0};  
  24.     int i=0,j;  
  25.     while(c[i]!='\0')  
  26.     {  
  27.         if(c[i]!='.'||c[i]!='!'||c[i]!=',')  
  28.         a[c[i]-'a']++;  
  29.         printf("%d\t",i++);  
  30.     }  
  31.     for(j=0;j<26;j++)  
  32.     {  
  33.           
  34.         printf("%c:%d\n",j+'a',a[j]);  
  35.     }  
  36.       
  37. }  
  38. void decypher(char *c,char *hashmap,int a,int b,int d)  
  39. {  
  40.     int i=0;  
  41.     int char_pos;//record the caractor's position  
  42.     while(c[i]!='\0')  
  43.     {  
  44.         char_pos=c[i]-'a';  
  45.         //printf("char_pos:%d\n",char_pos);  
  46.         if(c[i]!=' ')  
  47.         {  
  48.             printf("%c",hashmap[char_pos]);  
  49.         }  
  50.         else  
  51.         {  
  52.             printf(" ");  
  53.         }  
  54.         i++;  
  55.     }  
  56. }  
  57. void createHash(char *c,int a,int b,int d)  
  58. {  
  59.     int i;  
  60.     char encode[29];  
  61.     for(i=0;i<29;i++)  
  62.     {  
  63.         encode[i]=alphabet[(a*i+b)%d];  
  64.         printf("%c",encode[i]);  
  65.     }  
  66.     for(i=0;i<29;i++)  
  67.     {  
  68.         c[encode[i]-'a']=alphabet[i];  
  69.     }  
  70.   
  71.     printf("\n%s\n",alphabet);  
  72. }  

最终运行结果:


解密结果:

frequency analysis is based on the fact that, in any given stretch of written language, certain letters and combinations of letters occur withvarying frequencies. moreover, there is a charactistic distribution of letters that is roughly the same for almost all samples of that language.

转载自:http://blog.csdn.net/silangquan/article/details/8760297


上边那个有些错误。。。(,。!没映射过去)

下边这个我修改过了,只是简单的修改

#include<stdio.h>
void analyze(char *c);
void decypher(char *c,char *hashmap);
void createHash(char *hashmap,int a,int b,int d);
char alphabet[]="abcdefghijklmnopqrstuvwxyz,.!";
int main()
{
    char ch1[10000]="jgc!.chr, dhdw,nbn bn kdncy oh uxc jdru uxdul bh dh, qbfch nugcurx oj mgbuuch wdhq.dqcl rcgudbh wcuucgn dhy roakbhdubohn oj wcuucgn orr.g mbuxfdg,bhq jgc!.chrbcns aogcofcgl uxcgc bn d rxdgdrubnubr ybnugbk.uboh oj wcuucgn uxdu bn go.qxw, uxc ndac jog dwaonu dww ndavwcn oj uxdu wdhq.dqcs";
    char hash[29];

    printf("Paragragh info:\n");
    analyze(ch1);
    printf("\nAfter decyphered:\n");
    createHash(hash,7,3,29);
    printf("\n%s\n",ch1);
    decypher(ch1,hash);
    return 1;
}
void analyze(char *c)
{
    int a[26]={0};
    int i=0,j;
    while(c[i]!='\0')
    {
        if(c[i]!='.'||c[i]!='!'||c[i]!=',')
        a[c[i]-'a']++;
        i++;
    }
    for(j=0;j<26;j++)
    {

        printf("%c:%d\n",j+'a',a[j]);
    }

}
void decypher(char *c,char *hashmap)
{
    int i=0;
    int char_pos;//record the caractor's position
    while(c[i]!='\0')
    {
        char_pos=c[i]-'a';
        //printf("char_pos:%d\n",char_pos);
        if(c[i]!=' ')
        {
            if(c[i]==',')
                printf("l");
            else if(c[i]=='.')
                printf("s");
            else if(c[i]=='!')
                printf("z");
            else
                printf("%c",hashmap[char_pos]);
        }
        else
        {
            printf(" ");
        }
        i++;
    }
}
void createHash(char *hashmap,int a,int b,int d)
{
    int i;
    char encode[29];
    for(i=0;i<29;i++)
    {
        encode[i]=alphabet[(a*i+b)%d];
        printf("%c",encode[i]);
    }
    for(i=0;i<29;i++)
    {
        if(encode[i]-'a'>=0)
           hashmap[encode[i]-'a']=alphabet[i];
    }

    printf("\n%s\n",alphabet);

    printf("hashmap中的数据\n");
    for(i=0;i<29;i++)
      printf("%c ",hashmap[i]);
    printf("\nencode中的数据\n");
    for(i=0;i<29;i++)
      printf("%c ",encode[i]);
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值