<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    放翁(文初)的一畝三分地

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      210 隨筆 :: 1 文章 :: 320 評論 :: 0 Trackbacks
        下面是一段簡單的判斷一個ip是否在一組ip中的函數(shù),其中ip和ip組的表達(dá)方式可以為這樣(ip="192.3.22.34",iplist="123.21.23.11,121.2.11.234,12.*.23.*"),下面紅色部分是開始一個同學(xué)寫的,藍(lán)色部分是后來我嘗試修改的。要說明的就以下幾點(diǎn):
         1.很多時候優(yōu)化可以在海量運(yùn)算之前做好準(zhǔn)備,例如分析的數(shù)據(jù)先做預(yù)處理,因?yàn)橥勺x性和計(jì)算效率會有沖突。
         2.如果沒有緩存,那么構(gòu)建利于高效計(jì)算的代價可能超出簡單但計(jì)算效率一般的情況。
         3.在數(shù)據(jù)量很大的情況下,如何節(jié)省存儲直接決定你是否能夠緩存這些數(shù)據(jù)用于下次計(jì)算。

        有興趣的同學(xué)可以執(zhí)行以下下面一些代碼(拷貝到eclipse格式化看和執(zhí)行比較好):
        改動的主要內(nèi)容在于對數(shù)據(jù)作預(yù)處理時增加了一點(diǎn)轉(zhuǎn)換,6位byte作為支持ipv6的存儲,第7位作為標(biāo)識位來便于避免不需要的比對。
        用到了org.apache.commons.lang.StringUtils,它的split方法就是采用簡單的substring而不是pattern,效率很高,特別對于海量計(jì)算。

       具體的測試代碼:
       public static void  main(String[] args)
     {
      long beg = System.currentTimeMillis();
      
      //下面這些代碼是用于存粹比較計(jì)算時,對白名單做預(yù)編譯和緩存
      byte[][] whiteIps = prepare("12.24.23.123,12.25.23.255,12.24.23.17,*.25.*.*,12.24.*.*");
      
      String[] allowIps = StringUtils.split("12.24.23.123,12.25.23.255,12.24.23.17,*.25.*.*,12.24.*.*",",");
      List<String[]> whiteIps2 = new ArrayList<String[]>();
      if (null != allowIps && allowIps.length > 0) {
       for (int i = 0; i < allowIps.length; i++) {
        //把每個ip按“.”拆開,得到一個四位的數(shù)組
        String[] ipParse = StringUtils.split(allowIps[i], ".");
        whiteIps2.add(ipParse);
       }
      }
      
      for(int i = 0 ; i < 1000000 ; i++)
      {
       //第一組對比,增加了多一點(diǎn)的預(yù)處理,性能下降
       //checkAppIpWhite("12.24.23.123,12.25.23.255,12.24.23.17,*.25.*.*,12.24.*.*","12.24.23.19");
       //checkAppIpWhite("12.24.23.123,12.25.23.255,12.24.23.17,*.25.*.*,12.24.*.*","12.24.23.11");
       //checkAppIpWhiteV2("12.24.23.123,12.25.23.255,12.24.23.17,*.25.*.*,12.24.*.*","12.24.23.19");
       //checkAppIpWhiteV2("12.24.23.123,12.25.23.255,12.24.23.17,*.25.*.*,12.24.*.*","12.24.23.11");
       
       //存粹的比較計(jì)算,性能上升
    //   checkAppIpWhite(whiteIps2,"12.24.23.19");
    //   checkAppIpWhite(whiteIps2,"12.24.23.11");  
       checkAppIpWhiteV2(whiteIps,"12.24.23.19");
       checkAppIpWhiteV2(whiteIps,"12.24.23.11");
      }
      
      System.out.println("end test : " +  (System.currentTimeMillis() - beg));
     }


    老的比較代碼函數(shù)如下:
    public static boolean checkAppIpWhite(String ipWhilte,String remoteIp){
      if(StringUtils.isEmpty(ipWhilte) || StringUtils.isEmpty(remoteIp)){
       return true;
      }
      String[] allowIps = StringUtils.split(ipWhilte,",");
      List<String[]> whiteIps = new ArrayList<String[]>();
      if (null != allowIps && allowIps.length > 0) {
       for (int i = 0; i < allowIps.length; i++) {
        //把每個ip按“.”拆開,得到一個四位的數(shù)組
        String[] ipParse = StringUtils.split(allowIps[i], ".");
        whiteIps.add(ipParse);
       }
      }
      String[] requestParse = StringUtils.split(remoteIp, ".");
      for (String[] whiteIp : whiteIps) {
       if (ipsEqual(requestParse, whiteIp)) {
        return true;
       }
      }
      return false;
     }
     
     public static boolean checkAppIpWhite(List<String[]> whiteIps,String remoteIp){
      String[] requestParse = StringUtils.split(remoteIp, ".");
      for (String[] whiteIp : whiteIps) {
       if (ipsEqual(requestParse, whiteIp)) {
        return true;
       }
      }
      return false;
     }
     
     //判斷兩個ip是否相等
     public static boolean ipsEqual(String[] requestIp, String[] whiteIp) {
      boolean equal = false;
      
      //判斷白名單ip是否在列表中必須要兩個ip都不為空進(jìn)行比較
      if (requestIp != null && whiteIp != null && requestIp.length == whiteIp.length) {   
       if (requestIp[0].equals(whiteIp[0])
         && requestIp[1].equals(whiteIp[1])
         && ("*".equals(whiteIp[2]) || requestIp[2]
           .equals(whiteIp[2]))
         && ("*".equals(whiteIp[3]) || requestIp[3]
           .equals(whiteIp[3]))) {
        equal = true;
       }
      }
      
      return equal;
     }

        

    新的代碼:
    public static boolean checkAppIpWhiteV2(String ipWhite,String remoteIp){
      
      if(StringUtils.isEmpty(ipWhite) || StringUtils.isEmpty(remoteIp)){
       return true;
      }
      
      byte[][] whiteIps = prepare(ipWhite);
      
      byte[] rIp = convertIp2Bytes(remoteIp);
      
      return isInclude(whiteIps,rIp);
      
     }
     
     public static boolean checkAppIpWhiteV2(byte[][] whiteIps,String remoteIp)
     {
      byte[] rIp = convertIp2Bytes(remoteIp);
      
      return isInclude(whiteIps,rIp);
     }
     
     public static  boolean isInclude(byte[][] whiteIps,byte[] rIp)
     {
      boolean result = false;
      
      for(byte[] whiteIp : whiteIps)
      {
       for(int i = 1; i < 7; i++)
       {
        byte n = (byte)(1 << (i-1));
        
        if ((whiteIp[0] & n) != n)
        {
         if (i == 6)
          return true;
         else
          continue;
        }
        else
        {
         if (whiteIp[i] != rIp[i-1])
          break;
        }
        
        
        if (i == 6)
        {
         return true;
        }
       }
      }
      
      return result;
     }
     
     public static byte[] convertIp2Bytes(String remoteIp)
     {
      byte[] result = new byte[6];
      
      String[] points = StringUtils.split(remoteIp,".");
      
      int cursor = 0;
      
      for(String point : points)
      {
       int i = Integer.parseInt(point);
       
       if (i > Byte.MAX_VALUE)
        result[cursor] = (byte)(i - Byte.MAX_VALUE);
       else
        result[cursor] = (byte)i; 
       
       cursor += 1;
      }
      
      return result;
     }
     
     public static byte[][] prepare(String ipWhite)
     {
      String[] allowIps = StringUtils.split(ipWhite,",");//性能很好
      byte[][] result = new byte[allowIps.length][7];
      
      int cursorX = 0;
      
      for(String allowIp : allowIps)
      {
       String[] points = StringUtils.split(allowIp,".");
       
       int cursorY = 0;
       byte checkbits = 0;
       
       for(String point : points)
       {
        if (!point.equals("*"))
        {
         checkbits += 1 << cursorY;
         
         int i = Integer.parseInt(point);
         
         if (i > Byte.MAX_VALUE)
          result[cursorX][cursorY + 1] = (byte)(i - Byte.MAX_VALUE);
         else
          result[cursorX][cursorY + 1] = (byte)i; 
        }
        cursorY += 1;
       }
       
       result[cursorX][0] = checkbits;
       cursorX += 1;
      }
      
      return result;
      
     }
       
    posted on 2011-04-13 23:11 岑文初 閱讀(4601) 評論(1)  編輯  收藏

    評論

    # re: 一段代碼,幾句話 2011-04-28 10:46 北京王錚
    這個還可以再進(jìn)一步優(yōu)化下吧  回復(fù)  更多評論
      


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 青柠影视在线观看免费| 久久久久久国产精品免费免费 | 国产精品亚洲不卡一区二区三区| 一级中文字幕乱码免费| 亚洲一区精品中文字幕| 日韩成全视频观看免费观看高清| 国产日韩在线视频免费播放| 精品亚洲成a人片在线观看| 日本一道一区二区免费看 | 亚洲成AV人片在线观看ww| 男女免费观看在线爽爽爽视频 | 永久黄色免费网站| 菠萝菠萝蜜在线免费视频| 亚洲午夜久久久精品影院| 国产一区二区三区免费在线观看| 人妻在线日韩免费视频| 亚洲人成色4444在线观看| 亚洲精品卡2卡3卡4卡5卡区| 久久不见久久见免费影院| 波多野结衣免费一区视频 | 美女扒开尿口给男人爽免费视频| 亚洲人成网站影音先锋播放| 免费看国产曰批40分钟| 国产成人精品免费视频大| 一级免费黄色毛片| 亚洲欧洲无码一区二区三区| 亚洲免费在线播放| 亚洲精品成人a在线观看| 无码日韩精品一区二区免费| 最近国语视频在线观看免费播放 | 久久精品国产亚洲一区二区三区| 亚洲一级毛片免费在线观看| 成人A毛片免费观看网站| 亚洲色精品三区二区一区| 久久久久久亚洲av成人无码国产 | 亚洲乱码一区二区三区国产精品| 亚洲人成网亚洲欧洲无码久久| 高清国语自产拍免费视频国产| 99久久精品免费精品国产| 国产精品内射视频免费| 亚洲AⅤ男人的天堂在线观看|