您的位置:首页 > 其它

关于密码安全问题

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分的细心呀!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: