密码强度检测之C语言实现

1 方案得分项

一、密码长度:

  • 公式 :+(n*4),其中n表示密码长度

二、大写字母:

  • 公式:+((len-n)*2),其中n表示大写字母个数,len表示密码长度

三、小写字母:

  • 公式:+((len-n)*2),其中n表示小写字母个数,len表示密码长度

四、数字:

  • 公式:+(n*4),其中n表示数字个数
  • 条件:满足n < len,才能得到加分,len表示密码长度

五、符号:

  • 公式:+(n*6),其中n表示符号个数

六、位于中间的数字或符号:

  • 公式:+(n*2),其中n表示位于中间的数字或符号个数

七、最低条件得分:

  • 公式:+(n*2),其中n表示满足的最低条件条目数
  • 条件:只有满足最低条件,才能得到加分

其中最低条件的条目如下:

  • 1.密码长度不小于8位
  • 2.包含大写字母
  • 3.包含小写字母
  • 4.包含数字
  • 5.包含符号

最低条件要求满足条目1并至少满足条目2-5中的任意三条。

2 方案减分项

一、只有字母:

  • 公式:-n,其中n表示字母个数

二、只有数字:

  • 公式:-n,其中n表示数字个数

三、重复字符数(大小写敏感):

该项描述复杂,具体计算方法见如下示例程序:

四、连续大写字母:

  • 公式:-(n*2),其中n表示连续大写字母出现的次数
  • 举例:如输入AUB,则n=2

五、连续小写字母:

  • 公式:-(n*2),其中n表示连续小写字母出现的次数
  • 举例:如输入aub,则n=2

六、连续数字:

  • 公式:-(n*2),其中n表示连续数字出现的次数
  • 举例:如输入381,则n=2

七、正序或逆序字母:

  • 公式:-(n*3),其中n表示连续发生的次数
    • 正序或逆序是指字母表中的顺序
    • 不区分大小写
  • 条件:只有连续3个字母或以上,才会减分,
  • 例1:如输入ABC,则n=1
  • 例2:如输入dcBA,则n=2

八、正序或逆序数字:

  • 公式:-(n*3),其中n表示连续发生的次数
  • 条件:只有连续3个数字或以上,才会减分
  • 例1:如输入123,则n=1,
  • 例2:如输入4321,则n=2
  • 例3:如输入12,则不会减分

九、正序或逆序符号:

  • 公式:-(n*3),其中n表示连续发生的次数
  • 条件:只有连续3个符号或以上,才会减分

3 方案等级划分

根据密码评分,将密码划分成以下5个等级:

  • >= 80: 非常强(VERY_STRONG)
  • >= 60: 强(STRONG)
  • >= 40: 好(GOOD)
  • >= 20: 弱(WEAK)
  • >= 0: 非常弱( VERY_WEAK)
int passwdmeter(char *passwd)
{
	int i = 0;
	//1.密码长度
	int passwdlen;
	passwdlen = strlen(passwd);

	//2~5.大小写字母个数,数字个数,符号个数
	int UppercaseLetters = 0;
	int LowercaseLetters = 0;
	int Numbers = 0,Symbols = 0;
	for(i = 0;i < passwdlen; i++)
	{
		if (passwd[i]>='a' && passwd[i] <= 'z')
			LowercaseLetters++;
		else if (passwd[i]>='A' && passwd[i] <= 'Z')
			UppercaseLetters++;
		else if(passwd[i]>='0' && passwd[i] <= '9')
			Numbers++;
		else
			Symbols++;
	}
	
	//6.位于中间的数字或符号
	int MiddleNumbersorSymbols = Numbers+Symbols;

	if (passwd[0]>='a' && passwd[0] <= 'z') ;
	else if (passwd[0]>='A' && passwd[0] <= 'Z') ;
	else if(passwd[0]>='0' && passwd[0] <= '9')
		MiddleNumbersorSymbols--;
	else
		MiddleNumbersorSymbols--;
	
	if (passwd[passwdlen - 1]>='a' && passwd[passwdlen - 1] <= 'z') ;
	else if (passwd[passwdlen - 1]>='A' && passwd[passwdlen - 1] <= 'Z') ;
	else if(passwd[passwdlen - 1]>='0' && passwd[passwdlen - 1] <= '9')
		MiddleNumbersorSymbols--;
	else
		MiddleNumbersorSymbols--;

	//7.最低条件得分
	int Requirements = 0;
	if(UppercaseLetters > 0)Requirements++;
	if(LowercaseLetters > 0)Requirements++;
	if(Numbers > 0)Requirements++;
	if(Symbols > 0)Requirements++;
	if(passwdlen > 8)Requirements++;

	//总加得分
	int Bonus = passwdlen*4 + Symbols*6 + MiddleNumbersorSymbols*2;
	if (UppercaseLetters)Bonus+= (passwdlen - UppercaseLetters)*2;
	if (LowercaseLetters)Bonus+= (passwdlen - LowercaseLetters)*2;
	if (Requirements > 3)Bonus+= Requirements*2;
	if (Numbers != passwdlen)Bonus+= Numbers*4;

	//1.只有字母
	int LettersOnly = 0;
	if (UppercaseLetters + LowercaseLetters == passwdlen)
		LettersOnly = passwdlen;

	//2.只有数字
	int NumbersOnly = 0;
	if (Numbers == passwdlen)
		NumbersOnly = passwdlen;

	//3.重复字符数(大小写敏感)
	int RepeatCharacters = 0;
	int repChar = 0;
	for(i = 0; i < passwdlen; i++) {
		int exists = 0;
		int j = 0;
		for (j = 0; j < passwdlen; j++) {
		    if (passwd[i] == passwd[j] && i != j) {
		        exists = 1;
		        RepeatCharacters += abs(passwdlen/(j-i));
		    }
		}
		if (exists) {
		    repChar++;
		    int unqChar = passwdlen - repChar;
		    RepeatCharacters = (unqChar) ? ceil(RepeatCharacters/(double)unqChar) : ceil(RepeatCharacters);
		}
	}

	//4~6.连续大小写字母,数字
	int ConsecutiveUppercaseLetters = 0;
	int ConsecutiveLowercaseLetters = 0;
	int ConsecutiveNumbers			= 0;

	int flag = 0;//1-小写,2-大写,3-数字
	int count = 0;
	for(i = 0 ;i < passwdlen;i++)
	{
		if(i == 0){
			if (passwd[i]>='a' && passwd[i] <= 'z'){flag = 1;count = 1;}
			else if (passwd[i]>='A' && passwd[i] <= 'Z'){flag = 2;count = 1;}
			else if(passwd[i]>='0' && passwd[i] <= '9'){flag = 3;count = 1;}
		}else
		{
			int tmpflag = 0;
			if (passwd[i]>='a' && passwd[i] <= 'z')
			{
				tmpflag = 1;
			}
			else if (passwd[i]>='A' && passwd[i] <= 'Z')
			{
				tmpflag = 2;
			}
			else if(passwd[i]>='0' && passwd[i] <= '9')
			{
				tmpflag = 3;
			}else
			{
				tmpflag = 0;
			}

			if(tmpflag == flag)
				count++;
			else
			{
				if(count >= 2)
				{
					switch(flag)
					{
						case 1:
							ConsecutiveLowercaseLetters += count-1;break;
						case 2:
							ConsecutiveUppercaseLetters += count-1;break;
						case 3:
							ConsecutiveNumbers += count-1;break;
						default:
						break;
					}
				}
				flag = tmpflag;
				count = 1;
			}
		}
	}

	if(count >= 2)
	{
		switch(flag)
		{
			case 1:
				ConsecutiveLowercaseLetters += count-1;break;
			case 2:
				ConsecutiveUppercaseLetters += count-1;break;
			case 3:
				ConsecutiveNumbers += count-1;break;
			default:
			break;
		}
	}
	
	//7~9 正序或者逆序的字母数字及符号
	int SequentialLetters = 0;

	int Sequenflag = 0;//1-正序,2-反序
	int Sequencount = 1; 
	for(i = 1 ;i < passwdlen;i++)
	{
		int value = passwd[i];
		if(passwd[i]>='a' && passwd[i] <= 'z' && passwd[i-1]>='A' && passwd[i-1] <= 'Z')
			value = passwd[i] - 32;
		else if(passwd[i-1]>='a' && passwd[i-1] <= 'z' && passwd[i]>='A' && passwd[i] <= 'Z')
			value = passwd[i] + 32;
		
		int tmpflag = 0;
		if (value - 1 == passwd[i-1])
		{
			tmpflag = 1;
		}else if (value + 1 == passwd[i-1])
			tmpflag = 2;
		else 
			tmpflag = 0;

		if(Sequenflag == 0 && tmpflag != 0)
		{
			Sequencount = 1;
			Sequenflag = tmpflag;
		}
		
		if (tmpflag == Sequenflag)
		{
			Sequencount++;
		}else
		{
			if(Sequencount >= 3 && Sequenflag != 0)
				SequentialLetters += Sequencount-2;

			Sequencount = 1;
			Sequenflag = tmpflag;
		}
	}

	if(Sequencount >= 3 && Sequenflag != 0)
		SequentialLetters += Sequencount-2;
	
	//减分项计算
	int Bonus2 = LettersOnly + NumbersOnly + RepeatCharacters + (ConsecutiveUppercaseLetters+ConsecutiveLowercaseLetters+ConsecutiveNumbers)*2 + SequentialLetters*3;

	int sum = 0;
	if (Bonus - Bonus2 < 0)
		return 0;

	return (Bonus - Bonus2) > 100?100:(Bonus - Bonus2);
}

猜你喜欢

转载自blog.csdn.net/u012023606/article/details/83184442