关于密码安全问题
2015-12-03 01:02
330 查看
最近两天,朋友请教我一个挺有意思的密码安全的问题,由于感觉思路不是太难,于是我就没有在第一时间内将这道题做一下,只是给他说了一下思路,然而这道题的确有点难度,他一连两天都没有按照我的思路做出来,于是我就自己在他给的代码基础上做了改动,这道题颇有意思,很值得回味。 题如下: 密码
【问题描述】网上流传一句话:”常在网上飘啊,哪能不挨刀啊~”。其实要想能安安心心地上网其实也不难,学点安全知识就可以。 首先,我们就要设置一个安全的密码。那什么样的密码才叫安全的呢?一般来说一个比较安全的密码至少应该满足下面两个条件:
(1).密码长度大于等于8,且不要超过16。
(2).密码中的字符应该来自下面“字符类别”中四组中的至少三组。
这四个字符类别分别为:
1.大写字母:A,B,C…Z;
2.小写字母:a,b,c…z;
3.数字:0,1,2…9;
4.特殊符号:~,!,@,#,$,%,^;
给你一个密码,你的任务就是判断它是不是一个安全的密码。
【数据输入】输入数据有多组,对于每一组输入第一行包含一个数M,接下有M行,每行一个密码(长度最大可能为50),密码仅包括上面的四类字符输入0退出。
【数据输出】对于每个测试实例,判断这个密码是不是一个安全的密码,是的话输出YES,否则输出NO。
【样例输入】
3
a1b2c3d4
Linle@ACM
^~^@^@!%
0
【数据输出】
NO
YES
NO
第一眼看到这个题,我感觉需要用到getchar,后来同学一尝试,漏洞百出,于是我就想到了gets,然而不容置疑,gets存在安全问题,所以我并不喜欢用,最后只能用一个比较直观的办法。
首先,先不说其具体代码,我们先来审题,因为这道题的细节问题特别多,稍不小心就容易出问题而导致答案出错。
经过我的做题过程我注意到的问题有以下几点:
一:需要先输入一个限定密码组数的值,无上限规定,所以酌情处理;
二:密码需要是规定的四种字符,包括其中三种以上的才有可能为安全密码;
三:密码长度需要检验,在8~16之间;
四:定义数组要注意数据范围,密码最长可能为50,而每个字符串最后需要有一个’\0’结束符,所以理论上定义的数据范围需要是51;
五:最后需要输入“0”才能结束输入。
究此几点,我做过了三四次改动,因为我的编程习惯是先编写大致框架,再编写核心算法,最后才去补充那些细节问题,一方面可以顺路规范代码,另一方面可以检查代码的小问题。
由此,代码如下:
#include<stdio.h> int main() { int i=0,j=0,f=0,k=0,m=0,n=0,x=0,y=0,h[100],c=0; char MiMa[100][51]={'\0'}; scanf("%d",&i); for (; j<i; j++) { scanf("%s",MiMa[j]); } scanf("%d",&f); if (f==0)//输入0即可结束输入阶段????不对,这里有问题…… { for (j=0; j<i; j++) { m=0,n=0,x=0,y=0,c=0; for (k=0; k<51; k++) { if (MiMa[j][k]>='0'&&MiMa[j][k]<='9') { m=1; c++; } else if (MiMa[j][k]>='A'&&MiMa[j][k]<='Z') { n=1; c++; } else if (MiMa[j][k]>='a'&&MiMa[j][k]<='z') { x=1; c++; } else if (MiMa[j][k]=='~'||MiMa[j][k]=='!'||MiMa[j][k]=='@'||MiMa[j][k]=='#'||MiMa[j][k]=='$'||MiMa[j][k]=='%'||MiMa[j][k]=='^') { y=1; c++; } else if (MiMa[j][k]=='\0') { break; } } h[j]=m+n+x+y; if (h[j]>=3&&c>=8&&c<=16) { printf("yes\n"); } else { printf("no\n"); } } } return 0; }
经过做这道题,我弥补了一个自己的知识漏洞,曾经我以为char型的不能用来输入输出数字,可是当我去细看ASCII表时,发现0~9这十个数字也可以用char型表示出来,在表中有对应的ASCII值,这的确是意外收获,这样,就可以用char型来表示混合的数据了,真是太好了,以后再遇见此类问题我一定可以少纠结很长时间了……^_^ 真是万幸,在我最后的复查阶段,发现了一个问题,我的代码并不符合我前面所提到的第五点细节问题,它不是输入0才结束输入,只是输入0后可以执行后边的判断,而不输入0时就直接结束了程序,这是错误的,不应该用if那样子做,经过我的思考,感觉要用用do...while...语句了……虽说这是我第一次用,但是感觉还是用它是最合适的了。 更正后代码如下:
#include<stdio.h> int main() { int i=0,j=0,f=0,k=0,m=0,n=0,x=0,y=0,h[100],c=0; char MiMa[100][51]={'\0'}; scanf("%d",&i); for (; j<i; j++) { scanf("%s",MiMa[j]); } do//先做一次输入 { scanf("%d",&f); }while (f!=0);//符合则接着输入,直到输入的不符合时才结束输入环节 for (j=0; j<i; j++) { m=0,n=0,x=0,y=0,c=0; for (k=0; k<51; k++) { if (MiMa[j][k]>='0'&&MiMa[j][k]<='9') { m=1; c++; } else if (MiMa[j][k]>='A'&&MiMa[j][k]<='Z') { n=1; c++; } else if (MiMa[j][k]>='a'&&MiMa[j][k]<='z') { x=1; c++; } else if (MiMa[j][k]=='~'||MiMa[j][k]=='!'||MiMa[j][k]=='@'||MiMa[j][k]=='#'||MiMa[j][k]=='$'||MiMa[j][k]=='%'||MiMa[j][k]=='^') { y=1; c++; } else if (MiMa[j][k]=='\0') { break; } } h[j]=m+n+x+y;//大于等于3则有可能为安全密码 if (h[j]>=3&&c>=8&&c<=16)//并且字符在8~16个的为真正的安全密码 { printf("yes\n"); } else { printf("no\n"); } } return 0; }
至此,这道题完全结束了,最起码我这么认为,细节问题我也都考略到了,希望没什么新的细节没有注意到了,编程真的需要120分的细心呀!!!
相关文章推荐
- 小玩流媒体播放——HLS流媒体点播系统
- 轮转调度算法(RR)
- 关于java中的static
- UVa 11078 Ai-Aj(i<j)的最大值
- html css 内部有浮动元素的div的高度没有被撑开怎么办【转载】
- StrobeMediaPlayback的Javascript桥接
- 文件、目录和用户相关的一些shell命令学习
- 第一次开通技术博客,标记一下
- JavaScript中null和undefined的区别
- 知乎收藏夹
- db2像oracle一样使用hints(guidelines)
- python入门(5)
- Android自定义布局系列之一:流式布局(含TextView的点击事件)
- How do I get started with Node.js
- poj1840
- [知其然不知其所以然-12] intel_pstate忘记对cpu区别对待导致的问题
- 网页中加入VLC的播放RTSP流的控件(笔记)
- Ubuntu - Atom 编辑器 酷炫插件(activate-power-mode)
- 没有躲过的坑--std::string初始化、最快速判断字符串为空
- storm配置