利用数学方法来大大降低一个逻辑判断实现的难度的例子

来源:互联网 发布:java float 比较 编辑:程序博客网 时间:2024/04/30 06:03

 对于密码强度,分为弱、中、强三等级,我的判断规则是:

1。如果密码的位数在3~4位之间,如果只含有字母,那么强度为弱。
2。如果密码的位数在3~4位之间,,如果还含有数字,那么强度也为弱。
3。如果密码的位数在3~4位之间,如果含有非字母数字的字符,那么强度为中。
4。如果密码位数在5~7之间,只含有字母的强度为弱
5。如果密码位数在5~7之间,同时还有数字的强度为中。
6。如果密码位数在5~7之间,同时还有非字母数字字符的强度为强。
7。如果密码长度大于7,如果只含有字母,那么强度为中。
8。如果密码长度大于7,如果还含有数字的话强度为中。
9。如果密码长度大于7,如果含有非字母数字字符的话,强度为强。

如果此时昨晚规则的分析后就着手写代码的话,那要写一堆if嵌套了。这样做的话,很可能会使得逻辑陷入混乱,很有可能一些情况就被忽略过去了。更为严重的是,这样写严重降低了代码的可读性。如果我必须用这样的方式来写,那我首先会去写unit test,其次再附详细的doc或注释来说明。

Okay,那我们进一步来分析一下。我们上述的9个条件都是由密码长度密码复杂度两部分来结合判断出来的。那么我们可以拆分一下,如下图所示(请大家先只看第一个表格):(我点"insert image from gallery"后显示访问的资源不存在,无法从博客园这插入图片了,所以在首页可能看不到有图片)

大小: 10.26 K尺寸: 400 x 380浏览: 18 次点击打开新窗口浏览全图

我们现在写两个函数,分别计算长度和复杂度对应的强度,并返回。这里我们用{0,1,2}和{0,1,3}来表示(为什么后者是{0,1,3}在后面会讲到)那么我们可以很容易把上面的9个规则总结成第一个表格来表示。

到这里为止,我可以分别使用i和j来表示拆分后的强度的表示,好,现在我们可以去写清晰一点的if..else嵌套或if..switch嵌套了,这里我们可以用标识符了,采用了简单的分而治之的思想,整个规则也被简化为了7步了(读者可以自己考虑一下),思路清晰了许多。

但是目前为止,我们还是没有脱离嵌套条件分支语句的尴尬和不便

Okay,我们继续对这个逻辑的返回结果作分析:

强度:情况1,情况2 = {(i1,j1),(i2,j2),....} § [(i+j)min,(i+j)max]

Strong: F,I = {(!0,3)} § [4,5]
Medium: G,E,H,C = {(2,0),(!0,1),(3,0)} § [2,3]
Weak: A,B,D = {(0,!3),(1,0)} § [0,1]

好,这样结果就很清楚了,当返回的i+j在>3时,那么强度肯定是strong的,如果小于2,那么肯定是weak的,剩下的就是Medium的了。这样只要写一个switch就完成任务了(我只在有双分支的时候用if,2个以上的都用switch,学过编译原理的应该知道它比if效率高,可是.net中他俩有什么性能区别我不知道,但是如果不出意外,应该还是比if效率高吧)。

此文仅在提供一种分解问题和归类问题各部分结果的小方法,当然也有“运气成分”(这就是为什么用{0,1,3}不用{0,1,2}的原因)。抛砖引玉,希望能学到更好的解决办法。

接下来是通过JS来实现判断密码强度:

JavaScript代码
  1. <script type="text/javascript">   
  2.     var PasswordStrength ={   
  3.         Level : ["高,实在是高","还行啦","靠,这样也行"],   
  4.         LevelValue : [30,20,0],//强度值   
  5.         Factor : [1,2,5],//字符加数,分别为字母,数字,其它   
  6.         KindFactor : [0,0,10,20],//密码含几种组成的加数    
  7.         Regex : [/[a-zA-Z]/g,//d/g,/[^a-zA-Z0-9]/g] //字符正则数字正则其它正则   
  8.         }   
  9.     PasswordStrength.StrengthValue = function(pwd)   
  10.     {   
  11.         var strengthValue = 0;   
  12.         var ComposedKind = 0;   
  13.         for(var i = 0 ; i < this.Regex.length;i++)   
  14.         {   
  15.             var chars = pwd.match(this.Regex[i]);   
  16.             if(chars != null)   
  17.             {   
  18.                 strengthValue += chars.length * this.Factor[i];   
  19.                 ComposedKind ++;   
  20.             }   
  21.         }   
  22.         strengthValue += this.KindFactor[ComposedKind];   
  23.         return strengthValue;   
  24.     }    
  25.     PasswordStrength.StrengthLevel = function(pwd)   
  26.     {   
  27.         var value = this.StrengthValue(pwd);   
  28.         for(var i = 0 ; i < this.LevelValue.length ; i ++)   
  29.         {   
  30.             if(value >= this.LevelValue[i] )   
  31.                 return this.Level[i];   
  32.         }   
  33.     }   
  34.       
  35.     alert(PasswordStrength.StrengthLevel("23"));    
  36.     alert(PasswordStrength.StrengthLevel("abcd123"));        
  37.     alert(PasswordStrength.StrengthLevel("abcd!%23"));     
  38. </script>  
原创粉丝点击