首页 > 编程语言 >检测IPV6地址是否合法的Java工具类

检测IPV6地址是否合法的Java工具类

时间:2024-01-05 19:33:26浏览次数:35  
标签:Java string ipv6Address int charCounter 地址 IPV6 groupCounter

import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class ipv6 {
    private static final Character[] IPV6_CHARACTERS = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};

    private static final Set<Character> IPV6_CHARACTER_SET = new HashSet<>();

    private static final BigInteger MAXIMUM_VALUE_OF_IPV6_SEGMENT;
    private static final BigInteger MINIMUM_VALUE_OF_IPV6_SEGMENT;


    static {
        IPV6_CHARACTER_SET.addAll(Arrays.asList(IPV6_CHARACTERS));
        MAXIMUM_VALUE_OF_IPV6_SEGMENT = new BigInteger("FFFF", 16);
        MINIMUM_VALUE_OF_IPV6_SEGMENT = new BigInteger("0", 16);
    }

    /**
     * @param string 一个疑似为 ipv6 地址的字符串
     * @return FALSE or TRUE
     */

    public static Boolean ipv6IsLegal(String string) {
        // 如果特殊情况 直接返回结果
        if (string == null || string.isBlank()) {
            return Boolean.FALSE;
        }
        if (string.length() > 39 || string.length() < 2) {
            return Boolean.FALSE;
        }
        // 全转换为小写字符
        string = string.toLowerCase();
        // 判断是否有不符合的字符 开始
        for (Character character : IPV6_CHARACTER_SET) {
            if (!IPV6_CHARACTER_SET.contains(character)) {
                return Boolean.FALSE;
            }
        }
        // 判断是否有不符合的字符 结束
        // 如果有多个 ::
        int index = string.indexOf("::");
        int lastIndex = string.lastIndexOf("::");
        if (index != lastIndex) {
            return Boolean.FALSE;
        }
        if (string.equals("::")) {
            return Boolean.TRUE;
        }
        // 如果存在 :: 并且只存在一次
        if (index != -1) {
            String before = string.substring(0, index);
            String after = string.substring(index + 2);
            int count = 0;
            for (char c : before.toCharArray()) {
                if (c == ':') {
                    count++;
                }
            }
            for (char c : after.toCharArray()) {
                if (c == ':') {
                    count++;
                }
            }
            string = before + ":0".repeat(Math.max(0, 6 - count)) +
                    ":" +
                    after;
        }
        String[] strings = string.split(":");
        if (strings.length != 8) {
            return Boolean.FALSE;
        }
        for (String str : strings) {
            BigInteger bigInteger = new BigInteger(str, 16);
            if (bigInteger.compareTo(MAXIMUM_VALUE_OF_IPV6_SEGMENT) > 0 || bigInteger.compareTo(MINIMUM_VALUE_OF_IPV6_SEGMENT) < 0) {
                return Boolean.FALSE;
            }
        }
        return Boolean.TRUE;
    }

    /**
     * 复制于
     * <dependency>
     * <groupId>org.apache.tomcat.embed</groupId>
     * <artifactId>tomcat-embed-core</artifactId>
     * <version>10.1.17</version>
     * </dependency>
     *
     * @param ipv6Address ipv6Address
     * @return 统一格式的 ipv6Address
     */
    public static String canonize(String ipv6Address) {
        int ipv6AddressLength = ipv6Address.length();
        if (ipv6Address.contains(".")) {
            int lastColonPos = ipv6Address.lastIndexOf(58);
            int lastColonsPos = ipv6Address.lastIndexOf("::");
            if (lastColonsPos >= 0 && lastColonPos == lastColonsPos + 1) {
                ipv6AddressLength = lastColonPos + 1;
            } else {
                ipv6AddressLength = lastColonPos;
            }
        } else if (ipv6Address.contains("%")) {
            ipv6AddressLength = ipv6Address.lastIndexOf(37);
        }
        StringBuilder result = new StringBuilder();
        char[][] groups = new char[8][4];
        int groupCounter = 0;
        int charInGroupCounter = 0;
        int zeroGroupIndex = -1;
        int zeroGroupLength = 0;
        int maxZeroGroupIndex = -1;
        int maxZeroGroupLength = 0;
        boolean isZero = true;
        boolean groupStart = true;
        StringBuilder expanded = new StringBuilder(ipv6Address);
        int colonsPos = ipv6Address.indexOf("::");
        int length = ipv6AddressLength;
        int change = 0;
        int charCounter;
        int j;
        if (colonsPos >= 0 && colonsPos < ipv6AddressLength - 1) {
            charCounter = 0;
            for (j = 0; j < ipv6AddressLength; ++j) {
                if (ipv6Address.charAt(j) == ':') {
                    ++charCounter;
                }
            }
            if (colonsPos == 0) {
                expanded.insert(0, "0");
                ++change;
            }
            for (j = 0; j < 8 - charCounter; ++j) {
                expanded.insert(colonsPos + 1, "0:");
                change += 2;
            }
            if (colonsPos == ipv6AddressLength - 2) {
                expanded.setCharAt(colonsPos + change + 1, '0');
            } else {
                expanded.deleteCharAt(colonsPos + change + 1);
                --change;
            }

            length = ipv6AddressLength + change;
        }
        for (charCounter = 0; charCounter < length; ++charCounter) {
            char c = expanded.charAt(charCounter);
            if (c >= 'A' && c <= 'F') {
                c = (char) (c + 32);
            }
            if (c != ':') {
                groups[groupCounter][charInGroupCounter] = c;
                if (!groupStart || c != '0') {
                    ++charInGroupCounter;
                    groupStart = false;
                }
                if (c != '0') {
                    isZero = false;
                }
            }
            if (c == ':' || charCounter == length - 1) {
                if (isZero) {
                    ++zeroGroupLength;
                    if (zeroGroupIndex == -1) {
                        zeroGroupIndex = groupCounter;
                    }
                }
                if (!isZero || charCounter == length - 1) {
                    if (zeroGroupLength > maxZeroGroupLength) {
                        maxZeroGroupLength = zeroGroupLength;
                        maxZeroGroupIndex = zeroGroupIndex;
                    }
                    zeroGroupLength = 0;
                    zeroGroupIndex = -1;
                }
                ++groupCounter;
                charInGroupCounter = 0;
                isZero = true;
                groupStart = true;
            }
        }
        charCounter = groupCounter;
        for (groupCounter = 0; groupCounter < charCounter; ++groupCounter) {
            if (maxZeroGroupLength > 1 && groupCounter >= maxZeroGroupIndex && groupCounter < maxZeroGroupIndex + maxZeroGroupLength) {
                if (groupCounter == maxZeroGroupIndex) {
                    result.append("::");
                }
            } else {
                for (j = 0; j < 4; ++j) {
                    if (groups[groupCounter][j] != 0) {
                        result.append(groups[groupCounter][j]);
                    }
                }
                if (groupCounter < charCounter - 1 && (groupCounter != maxZeroGroupIndex - 1 || maxZeroGroupLength <= 1)) {
                    result.append(':');
                }
            }
        }
        j = result.length();
        if (result.charAt(j - 1) == ':' && ipv6AddressLength < ipv6Address.length() && ipv6Address.charAt(ipv6AddressLength) == ':') {
            result.delete(j - 1, j);
        }
        for (int i = ipv6AddressLength; i < ipv6Address.length(); ++i) {
            result.append(ipv6Address.charAt(i));
        }
        return result.toString();
    }

}

最后编辑时间:2024年1月5日19:24:02

标签:Java,string,ipv6Address,int,charCounter,地址,IPV6,groupCounter
From: https://www.cnblogs.com/tothk/p/17947928

相关文章

  • Java Thread Dump文件分析
    分析线程转储对于确定多线程进程中的问题非常有用,可以通过可视化单个线程转储的状态来解决死锁、锁争用和过多的CPU利用率等问题。通过在分析线程转储后纠正每个线程的状态,可以实现应用程序的最大吞吐量。例如,假设一个进程占用了大量CPU,我们可以找出是否有哪个线程占用CPU最多。如......
  • Java限流功能的实现
    在Java中,限流是一种常见的技术手段,用于控制系统的访问速率,以保护系统免受过载和滥用。以下是一些常见的Java限流实现方法:1.计数器限流这是一种简单而常见的限流方法。在该方法中,我们可以使用计数器来记录每个时间窗口内的请求数量,并与预设的阈值进行比较。如果请求数量超过......
  • 时代变了,Spring 官方抛弃了 Java 8!
    先容许我吐槽一句:Spring官方,窝草nm!原谅我很愤怒!最近编程导航星球和群友们反复问一个问题:为啥用IDEA创建SpringBoot项目时,不能选择Java8了?我本来以为是IDEA版本更新导致的Bug,开始还没在意。直到我今天自己初始化项目时才发现:卧槽,Java8真没了?!具体一点,应该是使用IDEA......
  • 【从零开始重学Java】第3天
    前情提示从零开始重学Java第0天从零开始重学Java第1天从零开始重学Java第2天表达式和流程控制语句表达式操作数常量(只有简单数据类型和String)变量运算符位运算只对字符char和整型生效Java里<<(算术)左移>>(算术)右移>>>无符号(逻辑)右移运算符优先......
  • JAVA方法重载(函数)
    [JAVA方法]方法重载重载指的是多个方法名称相同,但参数列表不同参数列表不同分为:参数个数不同参数类型不同参数的多类型顺序不同注意事项一个表达式中的最后结果以数据类型范围大的为结果的数据类型。无法因为返回值类型不同进行重载。参数传递对于引用类......
  • JavaScript——函数的call、apply、bind方法
    JavaScript的函数拥有三个方法:callapplybind这三个方法都可以改变函数被调用时,函数内部this的指向。至于区别,阅读下面代码即可一目了然:functionmyCall(context){constargs=[...arguments].slice(1)letresultcontext=context?context:window......
  • java 包和访问修饰符
    免责声明:java基础资料均来自于韩顺平老师的《循序渐进学Java零基础》教案,具体视频内容可以去B站观看,这些资料仅用于学习交流,不得转载用于商业活动java包和访问修饰符1.1包包的三大作用区分相同名字的类当类很多时,可以很好的管理类控制访问范围基本语法:pagckagecom.tes......
  • java面向对象:类(二)
    1.Java面向对象:类1.1作用域1.1.1基本使用面向对象中,变量作用域是非常重要的知识点在java编程中,主要的变量就是属性(成员变量)和局部变量我们所获得局部变量一般是指在成员方法中定义得变量java中作用域得分类:全局变量:也就是属性,作用域为整个类,可以不赋值,直接使用,因为有默......
  • JavaScript——数组的归并方法
    JavaScript的reduce和reduceRight的作用是通过遍历数组得到一个结果,原理如下:functionmyReduce(execute,initValue){constlength=this.lengthletresultfor(leti=0;i<length;i++){if(i===0){consthasInitValue=initV......
  • Java基础语法(下):程序流程控制
    程序流程控制顺序结构分支结构分支语句1:if-else结构if-else使用说明1、条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量2、语句块只有一条执行语句时,一对{}可以省略,但建议保留3、if-else语句结构,根据需要可以嵌套使用4、当if-else结构是“多选一”时,最......