首页 > 试题广场 >

卡中心密码安全规范

[编程题]卡中心密码安全规范
  • 热度指数:171 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
小明在卡中心工作,用到的很多系统账号都需要设置安全密码。密码如果符合以下规范可以称为安全密码:
1、密码至少包含6个字符,至多包含20个字符;
2、至少包含一个小写字母,至少包含一个大写字母,至少包含一个数字;
3、不能出现连续3个相同的字母。

请写一个检查密码是否为安全密码的函数。
输入为一个字符串作为密码,输出为将该密码改为安全密码的最小改变次数。如果它已经是安全密码,则返回0。
备注:插入、删除、或者替换一个字符,均视为改变一次。

输入描述:
输入为一个字符串作为密码。


输出描述:
输出为将该密码改为安全密码的最小改变次数。如果它已经是安全密码,则返回0。
示例1

输入

aB3ab3

输出

0
示例2

输入

aaaaaa

输出

2
示例3

输入

abcdefG

输出

1
import sys

s=raw_input()
if s.isupper():
        print(2)
        sys.exit()
if s.isdigit():
        print(2)
        sys.exit()
if s.islower():
        print(2)
        sys.exit()
if "0" or "1" or '2' or '3' or '4' or '5' or'6' or '7' or'8' or '9'not in s:
        print(1)
        sys.exit()
if s.isalpha():
        filter(lambda x:x not in "0123456789",s)
        if s.isupper():
                print(1)
                sys.exit()
        if s.islower():
                print(1)
                sys.exit()
print(0)
发表于 2018-04-18 21:57:01 回复(0)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;
 
/* password长度为len,不足长度z=6-len,超出长度a=len-20, 重复改变次数b,3种字符组缺失c项(c<=2),修改最少次数i
 * 6<=len<=20:b>=c  --> i=b【替换c次,替换b-c次】
 *             b<c   --> i=c【替换b次,替换c-b次】
 *
 * len<6:b<=1,c<=2,z>=1
 *        c>=b得知 i=c【插入c次】,z>=c得知i=z【插入z次】
 *        c<b得知 i=b,c=0【插入b次】,z<c得知i=c,z=1,c=2【插入c次】
 *        情况一:z>=c,c>=b  --> i=z【插入z次】
 *        情况二:z>=c,c<b   --> i=z【插入z次】
 *        情况三:z<c,c>=b   --> i=c【插入c次】
 *        情况四:z<c,c<b   --> z=1,c=2,b>2,不存在
 *
 * len>20:。。。。。。
 */
 
 
public class Main {
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        String password = scan.nextLine();
        System.out.println(check(password));
    }
    public static int check(String password){
        int i = 0;
        String regex = "";
        int len = password.length();
        if(len==0){
            return 6;
        }
        int z=6-len, a=len-20, b=0, c=0;
        int bin = 0;
        //重复字符需要改变次数b
        regex = ".*(\\S)\\1{2}.*";
        if(Pattern.matches(regex, password)){
            Matcher m = Pattern.compile("(\\S)\\1{2,}").matcher(password);
            while (m.find()) {
                String s =  (String) m.group();
                if(a>0 && (s.length()-a*bin)>a){
                    bin++;
                    b += (int)(s.length()-a)/3;
                }else{
                    b += (int)s.length()/3;
                }
            }
        }
        //3种字符组(小写字母,大写字母,数字)缺失c
        regex = ".*[A-Z].*";
        if(!Pattern.matches(regex, password)){
            c++;
        }
        regex = ".*[a-z].*";
        if(!Pattern.matches(regex, password)){
            c++;
        }
        regex = ".*[0-9].*";
        if(!Pattern.matches(regex, password)){
            c++;
        }
         
        if(len>=6 && len<=20){
            /*
             * b>=c  --> i=b【替换c次,替换b-c次】
             * b<c   --> i=c【替换b次,替换c-b次】
             */
            if(b>=c){
                i=b;
            }else{
                i=c;
            }
        }else if(len < 6){
            /*
             * 情况一:z>=c,c>=b  --> i=z【插入z次】
             * 情况二:z>=c,c<b   --> i=z【插入z次】
             * 情况三:z<c,c>=b   --> i=c【插入c次】
             * 情况四:z<c,c<b   --> z=1,c=2,b>2,不存在
             */
            if(z>=c){
                i=z;
            }else{
                i=c;
            }
        }else{
            /*
             * 6$$$$$$$$$$54321##############      a=10        14
             * AAAAAAAAAAAAAAAAAAAAA               a=1         7
             * aAAA...BBAAA#$%^!&AAAAAAa           a=5         6
             * aAAAAA.BBABC#$%^!&AAAAAAa
             * 先把超出的删除,具体是删除有3个以上连续重复的字符。然后再计算出剩余重复字符需要替换的次数b。
             *
             */
            b=0;
            regex = ".*(\\S)\\1{2}.*";
            if(Pattern.matches(regex, password)){
                Matcher m = Pattern.compile("(\\S)\\1{2,}").matcher(password);
                int acpy = a;//复制一份超出数a
                while (m.find()) {
                    String s =  (String) m.group();
                    int blen = s.length();//取得重复字符长度
                    if(acpy>0 && blen>=acpy && blen>5){
                        int sh = blen-5>acpy ? acpy : blen-5;//删除后,还剩余的s,最终s的长度应大于等于5
                        acpy -= sh;//删除
                        b += (blen-sh)/3;//剩余的b
                    }else if(acpy>0 && blen<=5){
                        acpy--;//删除
                        b += 0;
                    }else if(acpy>0 && blen<acpy){
                        acpy--;//删除
                        b += 0;
                    }else{
                        b += blen/3;
                    }
                }
                 
            }
            if(b>=c){
                i=a+b;
            }else{
                i=a+c;
            }
        }
        /*regex = "[a-zA-Z0-9]{6,20}";
        if(!Pattern.matches(regex, password)){
            int length = password.length();
            length = length>20 ? length-20 : 6-length;
            i += length;
        }*/
        return i;
    }
}

编辑于 2018-04-18 11:28:55 回复(0)
#include<stdio.h>
#include<string.h>
 
intsig[21]; //sig信号表示出现连续三个字符重复
intsig1[21]; //sig1信号表示第一次出现要求必须出现的字符所在的位置
charkey[100];
 
intfun1(charkey[100], intl, intnum);
intfun2(charkey[100], intl, intnum);
intfun3(charkey[100], intl, intnum);
intfun4(charkey[100], intl, intnum);
 
intfun1(charkey[100], intl, intnum)//处理连续三个字符重复相关,标记连续字符
{
    intx, y, z;
    inti;
    for(i = 0; (i < l-1);i++)
    {
        x = key[i], y = key[i + 1], z = key[i + 2];
        if((x == y) && (y == z))
            sig[i] = sig[i + 1] = sig[i + 2] = 1;
    }
    returnnum;
}
 
intunfun1(charkey[100], intl, intnum)//处理连续三个字符重复相关,去掉连续字符标记
{
    intx, y, z;
    inti;
    for(i = 0; (i < l - 2); i++)
    {
        x = key[i], y = key[i + 1], z = key[i + 2];
        if(sig[i]==1)
            if((x != y) || (y != z))
                sig[i] = 0;
    }
    x = key[i-1], y = key[i], z = key[i + 1];
    if((x != y) || (y != z))
        sig[i] = sig[i + 1] = 0;
    returnnum;
}
 
intfun2(charkey[100], intl, intnum)//处理数字相关
{
    inti = 0;
    intn = 0;
    for(i = 0; i < l; i++)
        if(key[i] >= int('0') && key[i] <= int('9'))
        {
            sig1[i] = 1;
            n++;
            break;
        }
    if(n!=0)
        returnnum;
    for(i = 0; i < l; i++)
    {
        if(sig[i] == 1)
        {
            key[i+2] = '1';
            sig1[i + 2] = 1;
            num++;
            sig[i] = sig[i + 1] = sig[i + 2] = 0;
            returnnum;
        }
    }
    for(i = 0; i < l; i++)
    {
        if(sig1[i] == 0)
        {
            key[i] = '1';
            sig1[i] = 1;
            num++;
            break;
        }
    }
    returnnum;
}
 
intfun3(charkey[100], intl, intnum)//处理小写字母相关
{
    inti = 0;
    inta = 0;
    for(i = 0; i < l; i++)
        if(key[i] >= int('a') && key[i] <= int('z'))
        {
            sig1[i] = 1;
            a++;
            break;
        }
    if(a != 0)
        returnnum;
    for(i = 0; i < l; i++)
    {
        if(sig[i] == 1)
        {
            key[i+2] = 'a';
            sig1[i + 2] = 1;
            num++;
            sig[i] = sig[i + 1] = sig[i + 2] = 0;
            returnnum;
        }
    }
    for(i = 0; i < l; i++)
    {
        if(sig1[i] == 0)
        {
            key[i] = 'a';
            sig1[i] = 1;
            num++;
            break;
        }
    }
    returnnum;
}
 
intfun4(charkey[100], intl, intnum)//处理大写字母相关
{
    inti = 0;
    intA = 0;
    for(i = 0; i < l;i++)
        if(key[i] >= int('A') && key[i] <= int('Z'))
        {
            sig1[i] = 1;
            A++;
            break;
        }
    if(A != 0)
        returnnum;
 
    for(i = 0; i < l; i++)
    {
        if(sig[i] == 1)
        {
            key[i+2] = 'A';
            sig1[i+2] = 1;
            num++;
            sig[i] = sig[i + 1] = sig[i + 2] = 0;
            returnnum;
        }
    }
    for(i = 0; i < l; i++)
    {
        if(sig1[i] == 0)
        {
            key[i] = 'A';
            sig1[i] = 1;
            num++;
            break;
        }
    }
    returnnum;
}
 
intIsRight(charkey[100],intl)
{
    inti;
    intnum = 0;
 
    //  sig[21] = { 0 }; //见鬼,去掉注释后key就丢了
 
    if(l>20)
    {
        for(i = 20; i < l; i++)
        {
            key[i] = 0;
            num++;
        }
        l = 20;
    }
 
    num = fun1(key, l, num);
    num = fun2(key, l, num);
    num = fun3(key, l, num);
    num = fun4(key, l, num);
 
    if(l < 6)
    {
        for(i = l; i < 6; i++)
        {
            key[i] = key[i - 1] + 1;
            num++;
        }
        l = 6;
    }
 
    for(i = 0; i < l-2; i++)
    {
        if((sig[i] == 1)&&(sig1[i]==0))
        {
            key[i+2] = (key[i+2]++)%128;
            num++;
            num = unfun1(key, l, num);
        }
        num = unfun1(key, l, num);
    }
 
    printf("%d\n", num);
    return0;
}
 
intmain()
{
    intl,i;
    ints = 1;
 
    while(s--)
    {
        sig[20] = sig1[21] = { 0 };
        gets(key);
        l = strlen(key);
        IsRight(key, l);
    }
    return0;
}

为啥我自己测试的时候
123456##############
这个例子是四次,到平台上就说是八次呢?
发表于 2018-04-16 20:07:46 回复(0)