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();
            }
        }
    }
    
  • 相关阅读:
    python基础-元组类型
    python基础-列表类型
    python基础-字符串类型
    python基础-数字类型
    python基础-循环
    python基础-短路和拷贝
    python基础-人机交互和运算符
    python基础-垃圾回收机制
    python基础-python介绍
    UCF Local Programming Contest 2017(2020-4-6)
  • 原文地址:https://www.cnblogs.com/hts-technology/p/11890623.html
Copyright © 2011-2022 走看看