关于密码安全问题

最近两天,朋友请教我一个挺有意思的密码安全的问题,由于感觉思路不是太难,于是我就没有在第一时间内将这道题做一下,只是给他说了一下思路,然而这道题的确有点难度,他一连两天都没有按照我的思路做出来,于是我就自己在他给的代码基础上做了改动,这道题颇有意思,很值得回味。
题如下:
密码

【问题描述】网上流传一句话:”常在网上飘啊,哪能不挨刀啊~”。其实要想能安安心心地上网其实也不难,学点安全知识就可以。 首先,我们就要设置一个安全的密码。那什么样的密码才叫安全的呢?一般来说一个比较安全的密码至少应该满足下面两个条件:
(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分的细心呀!!!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值