模拟问题之密码学
2016-02-13 18:02
344 查看
许多信息加密过程有着复杂的数学原理,但是一些简单的密码问题通过模拟即可解决。
POJ 3749 破译密码
http://poj.org/problem?id=3749
模运算模拟即可
UESTC_old - 1063
易位法字符串加密
密码学是一门既古老又年轻的学科。说它古老,是因为早在几千年前,人类就已经有了通信保密的思想,并先后出现了易位法和置换法等加密方法。到了1949 年,信息论的创始人香农(C.E.Shannon)论证了由传统的加密方法所获得的密文,几乎是都可攻破的,这使得密码学的研究面临着严重的危机。
直 至进入20世纪60年代,由于电子技术和计算机技术的迅速发展,以及结构代数、可计算性理论学科研究成果的出现,才使密码学的研究走出困境而进入了一个新 的发展时期;特别是美国的数据加密标准DES和公开密钥密码体制的推出,又为密码学的广泛应用奠定了坚实的基础。
虽然加密方法很多,但最 基本的加密方法只有两种,即易位法和置换法,其它方法大多是基于这两种方法形成的。易位法是按照一定的规则,重新安排明文中的比特或字符的顺序来形成密 文,而字符本身保持不变。按易位单位的不同又可分成比特易位和字符易位两种易位方式。前者的实现方法简单易行,并可用硬件实现,主要用于数字通信中;而后 者即字符易位法则是利用密钥对明文进行易位后形成密文。
具体方法是:假定有一密钥DCAB,其长度为4,字符串为I love China,去掉空格,四位四位分组,不足四位时用e补齐。具体见下图所示。输出时转化为大写输出。注意分组时要求先去掉空格,取列时按密钥的ASCII 码从小到大取,输出时要求英文字母全转换为大写
复制字符串时注意空格问题
处理字符串到数组时也要注意空格问题
(下面的代码不知道能不能行,OJ上居然没找到这题)
POJ 1107 W's Cipher
http://poj.org/problem?id=1107
大意:信息加密过程,不同的字符分成三组,每一组字符向左移动ki次。现在给出k1,k2,k3,给出密文,求出明文。
分析:右移解码,直接模拟。
POJ 2159 Ancient Cipher
http://poj.org/problem?id=2159
大意:明文经过替换和重新排列得到密文。现在给出明文和密文,求解他们是否是有转化关系。
分析:这题不是模拟题,算是侦探题,哈哈哈。明文经过上诉过程加密后各个字符的个数一定等于原文各个字符的个数。
POJ 3749 破译密码
http://poj.org/problem?id=3749
模运算模拟即可
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char str[205],s[20]; int main() { while(~scanf("%s",s)){ if(strcmp(s,"ENDOFINPUT")==0) break; getchar(); gets(str); int len=strlen(str); for(int i=0;i<len;i++){ if(str[i]<91&&str[i]>=65){ str[i]=(str[i]-65-5+26)%26+65; } } scanf("%s",s); printf("%s\n",str); } return 0; }
UESTC_old - 1063
易位法字符串加密
密码学是一门既古老又年轻的学科。说它古老,是因为早在几千年前,人类就已经有了通信保密的思想,并先后出现了易位法和置换法等加密方法。到了1949 年,信息论的创始人香农(C.E.Shannon)论证了由传统的加密方法所获得的密文,几乎是都可攻破的,这使得密码学的研究面临着严重的危机。
直 至进入20世纪60年代,由于电子技术和计算机技术的迅速发展,以及结构代数、可计算性理论学科研究成果的出现,才使密码学的研究走出困境而进入了一个新 的发展时期;特别是美国的数据加密标准DES和公开密钥密码体制的推出,又为密码学的广泛应用奠定了坚实的基础。
虽然加密方法很多,但最 基本的加密方法只有两种,即易位法和置换法,其它方法大多是基于这两种方法形成的。易位法是按照一定的规则,重新安排明文中的比特或字符的顺序来形成密 文,而字符本身保持不变。按易位单位的不同又可分成比特易位和字符易位两种易位方式。前者的实现方法简单易行,并可用硬件实现,主要用于数字通信中;而后 者即字符易位法则是利用密钥对明文进行易位后形成密文。
具体方法是:假定有一密钥DCAB,其长度为4,字符串为I love China,去掉空格,四位四位分组,不足四位时用e补齐。具体见下图所示。输出时转化为大写输出。注意分组时要求先去掉空格,取列时按密钥的ASCII 码从小到大取,输出时要求英文字母全转换为大写
复制字符串时注意空格问题
处理字符串到数组时也要注意空格问题
(下面的代码不知道能不能行,OJ上居然没找到这题)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=1005; struct node{ char val; char str ; int dth; }key[25]; int cmp(node a,node b){ return a.val<b.val; } char s ; char upper(char a){ if(a>=97) a-=32; return a; } int main() { //freopen("cin.txt","r",stdin); char code[25]; while(~scanf("%s",code)){ int len=strlen(code); for(int i=0;i<len;i++){ key[i].val=code[i]; key[i].dth=0; } getchar(); gets(s); int length=strlen(s); int dex=0; for(int i=0;i<length;i++){ if(s[i]==' ') continue; key[dex%len].str[key[dex%len].dth++]=s[i]; dex++; } int L=len*key[0].dth; for(int i=dex;i<L;i++){ key[i%len].str[key[i%len].dth++]='e'; } /*for(int i=0;i<len;i++){ for(int j=0;j<key[i].dth;j++) printf("%c",key[i].str[j]); cout<<endl; }*/ sort(key,key+len,cmp); for(int i=0;i<len;i++){ for(int j=0;j<key[0].dth;j++) printf("%c",upper(key[i].str[j])); } puts(""); } return 0; }
POJ 1107 W's Cipher
http://poj.org/problem?id=1107
大意:信息加密过程,不同的字符分成三组,每一组字符向左移动ki次。现在给出k1,k2,k3,给出密文,求出明文。
分析:右移解码,直接模拟。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=100; char str ; int vis ; char s1 ,s2 ,s3 ; char g1 ,g2 ,g3 ; int main() { //freopen("cin.txt","r",stdin); int k1,k2,k3; int top1,top2,top3; while(scanf("%d%d%d",&k1,&k2,&k3)&&(k1+k2+k3)){ getchar(); gets(str+1); memset(vis,0,sizeof(vis)); top1=top2=top3=0; int len=strlen(str+1); for(int i=1;i<=len;i++){ if(str[i]<='i'&&str[i]>='a'){ s1[top1++]=str[i]; vis[i]=1; } else if(str[i]<='r'&&str[i]>='j'){ s2[top2++]=str[i]; vis[i]=2; } else { s3[top3++]=str[i]; vis[i]=3; } } for(int i=0;i<top1;i++){ int dex=i; dex=(dex+k1)%top1; g1[dex]=s1[i]; } for(int i=0;i<top2;i++){ int dex=i; dex=(dex+k2)%top2; g2[dex]=s2[i]; } for(int i=0;i<top3;i++){ int dex=i; dex=(dex+k3)%top3; g3[dex]=s3[i]; } int i1=0,i2=0,i3=0; for(int i=1;i<=len;i++){ if(vis[i]==1){ printf("%c",g1[i1++]); } else if(vis[i]==2){ printf("%c",g2[i2++]); } else { printf("%c",g3[i3++]); } } printf("\n"); } return 0; }
POJ 2159 Ancient Cipher
http://poj.org/problem?id=2159
大意:明文经过替换和重新排列得到密文。现在给出明文和密文,求解他们是否是有转化关系。
分析:这题不是模拟题,算是侦探题,哈哈哈。明文经过上诉过程加密后各个字符的个数一定等于原文各个字符的个数。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N=105; char s1 ,s2 ; int c1[30],c2[30]; int main() { //freopen("cin.txt","r",stdin); while(~scanf("%s",s1)){ memset(c1,0,sizeof(c1)); memset(c2,0,sizeof(c2)); scanf("%s",s2); int len=strlen(s1); for(int i=0;i<len;i++){ int dex=s1[i]-'A'; c1[dex]++; } for(int i=0;i<len;i++){ int dex=s2[i]-'A'; c2[dex]++; } sort(c1,c1+30); sort(c2,c2+30); bool OK=1; for(int i=0;i<30;i++){ if(c1[i]!=c2[i]) { OK=0; break; } } if(OK) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- javaweb入门笔记(6)-JSP技术
- javaweb入门笔记(5)-cookie和session
- java移位操作符注意的问题
- mysql函数大全
- javaweb入门笔记(4)-request和response
- poj1088 2010.7.31
- poj1083 2010.7.31
- 268. Missing Number LeetCode
- javaweb入门笔记(3)-Servlet
- 中介者模式
- poj2430 2010.7.31
- Educational Codeforces Round 7
- javaweb入门笔记(2)-http入门
- Cursor
- Linux下忘记mysql密码该如何修改mysql密码
- 319. Bulb Switcher LeetCode
- csdn博客积分规则
- Hdu3231【拓扑排序】
- javaweb入门笔记(1)-Tomcat
- 【POJ】3468 A Simple Problem with Integers