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

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

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

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

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

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

       具體的測試代碼:
       public static void  main(String[] args)
     {
      long beg = System.currentTimeMillis();
      
      //下面這些代碼是用于存粹比較計算時,對白名單做預編譯和緩存
      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按“.”拆開,得到一個四位的數組
        String[] ipParse = StringUtils.split(allowIps[i], ".");
        whiteIps2.add(ipParse);
       }
      }
      
      for(int i = 0 ; i < 1000000 ; i++)
      {
       //第一組對比,增加了多一點的預處理,性能下降
       //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");
       
       //存粹的比較計算,性能上升
    //   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));
     }


    老的比較代碼函數如下:
    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按“.”拆開,得到一個四位的數組
        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都不為空進行比較
      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 岑文初 閱讀(4588) 評論(1)  編輯  收藏

    評論

    # re: 一段代碼,幾句話 2011-04-28 10:46 北京王錚
    這個還可以再進一步優化下吧  回復  更多評論
      


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


    網站導航:
     
    主站蜘蛛池模板: 国产午夜不卡AV免费| 亚洲精品一级无码鲁丝片| 国产日韩在线视频免费播放| 亚洲日韩乱码中文无码蜜桃 | 337p日本欧洲亚洲大胆色噜噜| 亚洲AV无码乱码在线观看| 久久不见久久见免费影院| 日韩在线不卡免费视频一区| 精品国产污污免费网站入口在线| 亚洲av无码日韩av无码网站冲| 亚洲国产综合第一精品小说| 久久久久久亚洲精品中文字幕| 国产av无码专区亚洲国产精品| 国产伦精品一区二区三区免费下载 | 成人免费午夜无码视频| 99热这里只有精品免费播放| 三年片免费高清版| 日韩毛片一区视频免费| 国产偷国产偷亚洲高清在线| 亚洲人成人网站18禁| 久久国产亚洲精品| 亚洲欧洲日本在线观看 | 日本黄网站动漫视频免费| 久久aa毛片免费播放嗯啊| a级毛片毛片免费观看永久| 久久国产精品免费一区| 精品国产福利尤物免费| 99热在线日韩精品免费| 91精品成人免费国产| 久操免费在线观看| 在线观看的免费网站无遮挡| 狼群影院在线观看免费观看直播| 精品一区二区三区免费毛片爱| 久久久久久AV无码免费网站 | 亚洲色欲色欱wwW在线| 亚洲老熟女五十路老熟女bbw| 亚洲成AV人片在WWW| 最新亚洲人成无码网www电影| 美女隐私免费视频看| 一级毛片免费不卡直观看| 国产伦精品一区二区免费|