zoukankan      html  css  js  c++  java
  • IPV6

    import java.util.Objects;
    public class Ipv6 implements Comparable<Ipv6>{
        private Long first;
        private Long second;
    
        public Ipv6(Long left, Long right) {
            this.first = left;
            this.second = right;
        }
        public Long getFirst() {
            return first;
        }
        public void setFirst(Long left) {
            this.first = left;
        }
        public Long getSecond() {
            return second;
        }
        public void setSecond(Long right) {
            this.second = right;
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Ipv6)) return false;
            Ipv6 that = (Ipv6) o;
            return Objects.equals(first, that.first) &&
                    Objects.equals(second, that.second);
        }
        @Override
        public int hashCode() {
            return Objects.hash(first, second);
        }
        @Override
        public int compareTo(Ipv6 o) {
            if(first.equals(o.first)){
                return second.compareTo(o.second);
            }else {
                return first.compareTo(o.first);
            }
        }
    }
    
    
    import org.apache.commons.lang.StringUtils;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    public class Ipv6Test {
        public static void main(String[] args) throws Exception {
    //        System.out.println("2001::".split("::").length);
            test(toIpv6StandardFormat("2001::1234"));
    
    //        System.out.println(Long.toHexString((-1L << 10)));
    //        Long start = System.currentTimeMillis();
    //        String[] ips4Test = new String[]{"FFFF:1111:FFFF:2222:1245:BA98:3210:4562",
    //                "FFFF:0:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "7654:0:FFFF:7654:562:222:7622:0", "0:0:0:0:0:0:0:0"};
    //        for (String testCase : ips4Test) {
    //            test(testCase);
    //        }
    //        System.out.println(System.currentTimeMillis() - start);
        }
    
        private static void test(String testCase) throws Exception {
            Ipv6 ipv6 = ipv6ToLongs(testCase);
            String ipString = longsToIpv6(ipv6);
            boolean eq = testCase.equalsIgnoreCase(ipString);
            System.out.println("本次测试 ipv6 地址: " + testCase
                    + ", 再转回 ipv6 字符串: " + ipString + ", 是否与原字符串相等: " + eq);
            System.out.println("网络位: " + longsToIpv6(getIpv6NetworkPart(testCase, 46)));
            if (!eq) {
                throw new IllegalStateException("本次测试未通过!testCase: " + testCase);
            }
        }
    
        /**
         * 将 IPv6 地址转为 两个long ,只支持冒分十六进制表示法
         */
        public static Ipv6 ipv6ToLongs(String ipString) {
            if (ipString == null || ipString.isEmpty()) {
                throw new IllegalArgumentException("ipString cannot be null.");
            }
            String[] ipSlices = ipString.split(":");
            if (ipSlices.length != 8) {
                throw new IllegalArgumentException(ipString + " is not an ipv6 address.");
            }
            long[] ipv6 = new long[2];
            for (int i = 0; i < 8; i++) {
                int index = i >> 2;
                String slice = ipSlices[i];
                // 以 16 进制解析
                long num = Long.parseLong(slice, 16);
                // 每组 16 位
                // 每个 long 保存四组,i >> 2 = i / 4
                ipv6[index] = ipv6[index] << 16;
                ipv6[index] = ipv6[index] | num;
                // a|=b的意思就是把a和b按位或然后赋值给a 按位或的意思就是先把a和b都换成2进制,然后用或操作,相当于a=a|b
            }
            return new Ipv6(ipv6[0], ipv6[1]);
        }
    
        public static String longsToIpv6(Ipv6 ipv6) {
            StringBuilder sb = new StringBuilder(32);
            Long[] numbers = new Long[]{ipv6.getFirst(), ipv6.getSecond()};
            for (int i = numbers.length - 1; i >= 0; i--) {
                // 每个 long 保存四组
                long numSlice = numbers[i];
                for (int j = 0; j < 4; j++) {
                    // 取最后 16 位
                    long current = numSlice & 0xFFFF;
                    sb.insert(0, ":" + Long.toString(current, 16));
                    // 右移 16 位,去除掉已经处理过的 16 位
                    numSlice >>= 16;
                }
            }
            // 去掉第一个的 :
            return sb.substring(1, sb.length());
        }
    
    
        public static boolean isIpv6(String ip) {
            String pattern = "^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$";
            Pattern r = Pattern.compile(pattern);
            Matcher m = r.matcher(ip);
            if (m.find()) {
                return true;
            } else {
                return false;
            }
        }
    
        public static boolean isContainIpv6(String str) {
            String pattern = "\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*";
            Pattern r = Pattern.compile(pattern);
            Matcher m = r.matcher(str);
            if (m.find()) {
                return true;
            } else {
                return false;
            }
        }
    
        public static Ipv6 getIpv6NetworkPart(String ipv6, int mask) throws Exception {
            Ipv6 ipv6Before = ipv6ToLongs(ipv6);
            //如果子网掩码<=64位,则网络位在第一个long,直接将第二个long置为0
            if (mask <= 64) {
                ipv6Before.setSecond(0L);
                ipv6Before.setFirst(ipv6Before.getFirst() & (-1L << (64 - mask)));
            } else {//如果子网掩码>64位,则网络位有落到第二个long,第一个long不变
                int leave = mask - 64;
                ipv6Before.setSecond(ipv6Before.getSecond() & ((-1L << (64 - leave))));
            }
            return ipv6Before;
        }
    
        //转化为ipv6标准格式
        public static String toIpv6StandardFormat(String str) throws Exception{
            if(str.equals("::")){
                return "0:0:0:0:0:0:0:0";
            }
            //处理以:: 结尾格式
            if(str.endsWith("::")){
                str = str+" ";
            }
            String[] ipPart = str.split("::");
            if(ipPart.length > 2){
                throw new Exception("not ipv6");
            }
            StringBuilder sb = new StringBuilder();
            if (ipPart.length == 1) {
               if(str.split(":").length == 8){
                   return str;
               }else {
                   throw new Exception("not ipv6");
               }
            } else {
                if(StringUtils.isBlank(ipPart[0])){
                    int tempLen = ipPart[1].split(":").length;
                    for(int i=1; i<= 8-tempLen; i++){
                        sb.append("0:");
                    }
                    sb.append(ipPart[1]);
                }else if(StringUtils.isBlank(ipPart[1])){
                    int tempLen = ipPart[0].split(":").length;
                    sb.append(ipPart[0]);
                    for(int i=1; i<= 8-tempLen; i++){
                        sb.append(":0");
                    }
                }else {
                    int len = 8 - ipPart[0].split(":").length - ipPart[1].split(":").length;
                    sb.append(ipPart[0]);
                    for(int i=1; i<= len; i++){
                        sb.append(":0");
                    }
                    sb.append(":"+ipPart[1]);
                }
                return sb.toString();
            }
        }
    }
    
  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/hts-technology/p/11890623.html
Copyright © 2011-2022 走看看