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

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

相关文章

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3

SpringBoot如何对密码等敏感信息进行脱敏处理

《SpringBoot如何对密码等敏感信息进行脱敏处理》这篇文章主要为大家详细介绍了SpringBoot对密码等敏感信息进行脱敏处理的几个常用方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录​1. 配置文件敏感信息脱敏​​2. 日志脱敏​​3. API响应脱敏​​4. 其他注意事项​​总结

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录

使用Java实现Navicat密码的加密与解密的代码解析

《使用Java实现Navicat密码的加密与解密的代码解析》:本文主要介绍使用Java实现Navicat密码的加密与解密,通过本文,我们了解了如何利用Java语言实现对Navicat保存的数据库密... 目录一、背景介绍二、环境准备三、代码解析四、核心代码展示五、总结在日常开发过程中,我们有时需要处理各种软

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

Windows 上如果忘记了 MySQL 密码 重置密码的两种方法

《Windows上如果忘记了MySQL密码重置密码的两种方法》:本文主要介绍Windows上如果忘记了MySQL密码重置密码的两种方法,本文通过两种方法结合实例代码给大家介绍的非常详细,感... 目录方法 1:以跳过权限验证模式启动 mysql 并重置密码方法 2:使用 my.ini 文件的临时配置在 Wi

Python从零打造高安全密码管理器

《Python从零打造高安全密码管理器》在数字化时代,每人平均需要管理近百个账号密码,本文将带大家深入剖析一个基于Python的高安全性密码管理器实现方案,感兴趣的小伙伴可以参考一下... 目录一、前言:为什么我们需要专属密码管理器二、系统架构设计2.1 安全加密体系2.2 密码强度策略三、核心功能实现详解

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

Oracle登录时忘记用户名或密码该如何解决

《Oracle登录时忘记用户名或密码该如何解决》:本文主要介绍如何在Oracle12c中忘记用户名和密码时找回或重置用户账户信息,文中通过代码介绍的非常详细,对同样遇到这个问题的同学具有一定的参... 目录一、忘记账户:二、忘记密码:三、详细情况情况 1:1.1. 登录到数据库1.2. 查看当前用户信息1.

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J