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

2024-06-07 06:18

本文主要是介绍破解凯撒密码(离散数学),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先来看以下恺撒密码。

离散数学的一道作业题。

凯撒密码作为一种最为古老的对称加密体制,在古罗马的时候都已经很流行,他的基本思想是:通过把字母移动一定的位数来实现加密和解密。例如,如果密匙是把明文字母的位数向后移动三位,那么明文字母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 positionwhile(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");elseprintf("%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]);
}


这篇关于破解凯撒密码(离散数学)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1038379

相关文章

MySQL修改密码的四种实现方式

《MySQL修改密码的四种实现方式》文章主要介绍了如何使用命令行工具修改MySQL密码,包括使用`setpassword`命令和`mysqladmin`命令,此外,还详细描述了忘记密码时的处理方法,包... 目录mysql修改密码四种方式一、set password命令二、使用mysqladmin三、修改u

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

mysql重置root密码的完整步骤(适用于5.7和8.0)

《mysql重置root密码的完整步骤(适用于5.7和8.0)》:本文主要介绍mysql重置root密码的完整步骤,文中描述了如何停止MySQL服务、以管理员身份打开命令行、替换配置文件路径、修改... 目录第一步:先停止mysql服务,一定要停止!方式一:通过命令行关闭mysql服务方式二:通过服务项关闭

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密

超级 密码加密 解密 源码,支持表情,符号,数字,字母,加密 可以将表情,动物,水果,表情,手势,猫语,兽语,狗语,爱语,符号,数字,字母,加密和解密 可以将文字、字母、数字、代码、标点符号等内容转换成新的文字形式,通过简单的文字以不同的排列顺序来表达不同的内容 源码截图: https://www.httple.net/152649.html

mysql导出导入数据和修改登录密码

导出表结构: mysqldump -uroot -ppassword -d dbname tablename>db.sql; 导出表数据: mysqldump -t dbname -uroot -ppassword > db.sql 导出表结构和数据(不加-d): mysqldump -uroot -ppassword dbname tablename > db.sql;

Ubuntu 环境下ssh的安装、使用以及免密码登录

以两台机器为例:     A12.12.10.11B12.12.10.13 安装: Ubuntu默认安装了ssh客户端,只需要在被登录的机器上安装ssh服务器即可: $ sudo apt-get install openssh-server     启动ssh服务器: $ sudo /etc/init.d/ssh start 查看是否启动成功: $ ps -ef |grep