關於正則效率問題(正則導致程序卡死)


前言:

  在Java中,正則的使用需要謹慎,好的正則可以方便我們的代碼,但是不好的正則,可能成為黑客攻擊的漏洞。類似本例子的正則,黑客可以組織不同的匹配字符,使得校驗不過,耗盡服務器資源(資源耗盡攻擊)。詳見正則的狀態機原理。

1.說明:2018/8/17:
    校驗輸入字符串是否合規,允許:100000000000^145^1^1000.00| 100000000000^145^1^1000.00| ....
    如此序列(100000000000^145^1^1000.00|)必須滿足1-18個,19個則失敗。
    寫正則:reg = ^(\\d{12}\\^\\d{3}\\^[123456]{1}\\^\\d+[\\.\\d+]*\\|){1,18}$
代碼:
String regex = "^(\\d{12}\\^\\d{3}\\^[123456]{1}\\^\\d+[\\.\\d+]*\\|){1,18}$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(prove);
if (!matcher.matches()) {
      return false;
}
return true;

  

2.問題:
    在測試案例中含有18個序列,正常通過。在案例增加到19個序列時,程序卡死。
3.分析:
    正則循環次數過多!導致資源耗盡或死循環。
4.解決方法:
    減少正則校驗的循環次數,改為程序循環!,直接傳遞切割好的數組,再對數組進行循環。
代碼:
String[] proves = accountProve.split("\\|");        
 if (proves.length > 18 || proves.length < 1) {
      return false;
  }
 for (String prove : proves) {
     String regex = "^(\\d{12}\\^\\d{3}\\^[123456]{1}\\^\\d+[\\.\\d+]*)$";
     Pattern pattern = Pattern.compile(regex);
     Matcher matcher = pattern.matcher(prove);
     if (!matcher.matches()) {
         return false;
      }
 }
return true;
      

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM