<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)航:
     
    主站蜘蛛池模板: 亚洲精品无码日韩国产不卡?V| 国产成人亚洲毛片| 亚洲国产人成中文幕一级二级| 亚洲国产成人久久综合碰| 福利免费观看午夜体检区| 男人j进入女人j内部免费网站| 美女黄频免费网站| 亚洲综合中文字幕无线码| 亚洲国产高清人在线| 亚洲色一色噜一噜噜噜| 免费乱码中文字幕网站| 成人国产mv免费视频| 在线观看特色大片免费视频| 永久免费无码网站在线观看| 久久久久久久免费视频| 免费下载成人电影| 免费在线看片网站| 久久亚洲精品国产精品| 亚洲ⅴ国产v天堂a无码二区| 国产精品亚洲а∨无码播放| 亚洲成AV人片在线观看ww| 国产国拍亚洲精品mv在线观看| 亚洲午夜电影在线观看高清 | 亚洲精品福利网站| 亚洲成人午夜电影| 亚洲日本香蕉视频观看视频| 精品久久久久久久久亚洲偷窥女厕| 中文字幕乱码亚洲精品一区 | 亚洲综合一区二区三区四区五区| 亚洲成a人片毛片在线| 美女黄频视频大全免费的| 99re在线免费视频| 99国产精品永久免费视频| 无码国产精品一区二区免费式影视| www国产亚洲精品久久久日本| 亚洲国产精品一区二区第四页| 亚洲综合激情六月婷婷在线观看| 国产综合成人亚洲区| 91免费福利精品国产| 免费看国产精品3a黄的视频| 男女啪啪永久免费观看网站|