jdk8-获取本机ip、判断ip范围、ip与long互转等

2023-05-16

在配置nginx的ip白名单时候,会通过ip段进行配置(如 10.10.10.10/24),就在思考这种配置怎么通过代码解析并判断,故通过搜索网络内容,并通过java编写测试代码。代码及说明来源网络,并进行了部分调整。故有疑问请提出来,本人小白一枚,勿喷
代码内容:获取本机ip、判断ip范围、ip与long互转等
IP: 网络地址
掩码: 指明一个IP地址的哪些位标识的是主机所在的子网。
网段:网络中可通信的部分,一般用子网第一个地址表示。
广播地址:专门用于同时向网络中所有工作站进行发送的一个地址;一般用子网最后一个地址表示。
可用子网ip:一般指子网中去除网段、广播地址的地址范围

参考

处理ip,java判断ip是否在指定的ip段范围内,给定的ip地址是否在某个ip段范围内,将字符串形式IP地址转换long类型
ip地址与掩码、网段、广播地址、可用ip范围
java实现 IP/掩码位 转换 ip段范围
192.168.和10.0.开头的IP、内网IP段、IP简介、分类——IP观止
JDK8 Java 中遇到null 和为空的情况,使用Optional来解决
什么是ip地址

代码

demo

代码参考自 参考内,并进行了部分重构

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Optional;

/**
 * Ip工具类
 *
 * @author z.y.l
 * @version v1.0
 * @date 2022/12/13
 */
public class IpUtil {
    private static final int I_32 = 32;
    /** ip 255.255.255.255 >>> 11111111111111111111111111111111 */
    private static final long VALIDATE_DATA = 4294967295L;
    private static final HashMap<Integer,String> NET_MASK = new HashMap<>();
    /** 1-255 正则 */
    private static final String REG_1_255 = "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])";
    /** 0-255 正则 */
    private static final String REG_0_255 = "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)";
    /** ip 正则 */
    private static final String IP_REGEX = "^" + REG_1_255 + "\\." + REG_0_255 + "\\." + REG_0_255 + "\\." + REG_0_255 + "$";
    static {
        /* 初始化掩码 */
        NET_MASK.put( I_32, long2ip( VALIDATE_DATA ) );
        for(int i = 1 ; i < I_32 ; i++ ){
            NET_MASK.put( I_32-i, long2ip( VALIDATE_DATA << i & VALIDATE_DATA ) );
        }
    }

    public static void main(String[] args) {
        String localIp = inetIp();
        System.out.println("本机ip:"+localIp);
        System.out.println("-------------");
        System.out.println(new IpInf("192.168.1.2", "255.255.254.0").toString());
        System.out.println(new IpInf("192.168.1.3", "255.255.255.0").toString());
        System.out.println("-------------");
        String ip="10.10.10.116";
        String startIP = "10.10.1.0";
        String endIP = "10.10.255.255";
        System.out.println("ip:10.10.10.116>>>"+ip2Long(ip));
        System.out.println("ip:10.10.10.116,startIP:10.10.1.0,endIP:10.10.255.255,>>>"+ipExistsIn(ip,startIP,endIP));
        System.out.println("-------------");
        //判断一个IP是否属于某个网段
        System.out.println("ip:10.2.1.0,cip:10.2.0.0/17,>>>"+ipIsIn("10.2.1.0", "10.2.0.0/17"));
    }
    /**
     * 获取 本机ip
     * @return 本机ip
     */
    public static String inetIp(){
        try {
            Enumeration<NetworkInterface> nif = NetworkInterface.getNetworkInterfaces();
            while (nif.hasMoreElements()) {
                NetworkInterface ni = nif.nextElement();
                Enumeration<InetAddress> inet = ni.getInetAddresses();
                while (inet.hasMoreElements()) {
                    InetAddress ia = inet.nextElement();
                    if (!ia.isLinkLocalAddress() && !ia.isLoopbackAddress() && ia instanceof Inet4Address) {
                        return ia.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            return null;
        }
        return "";
    }
    /** 判断一个ip地址是否在某个ip段范围内 */
    public static boolean ipExistsIn(String ip,String start,String end){
        long ipL = ip2Long(ip);
        return ( ip2Long(start) <= ipL ) && ( ip2Long(end) >= ipL );
    }
    /**
     * 功能:判断一个IP是不是在一个网段下的
     * 格式:isInRange("192.168.8.3", "192.168.9.10/22");
     */
    public static boolean ipIsIn(String ip,String cip){
        long ipL = ip2Long(ip);
        String[] split = cip.split("/");
        int mask = 0xFFFFFFFF << ( 32L - s2l(split[1]));
        long cipL = ip2Long(split[0]);
        return ( ipL & mask ) == ( cipL & mask );
    }
    /** 把long类型的Ip转为一般Ip类型:xx.xx.xx.xx */
    public static String long2ip(Long ip){
        Long tmp = Optional.ofNullable(ip).filter(l -> l >= 0 && l <= VALIDATE_DATA )
                .orElseThrow(()-> new RuntimeException(ip + " 数字 不在 有效ip范围."));
        // 255.0.0.0 ~ 1.0.0.0,0.255.0.0 ~ 0.1.0.0,0.0.255.0 ~ 0.0.1.0,0.0.0.255 ~ 0.0.0.1
        return (tmp>>>24) + "." + (tmp>>>16&255L) + "." + (tmp>>>8&255L) + "." + (tmp&255L);
    }
    /** 将字符串形式IP地址转换long类型 */
    public static long ip2Long(String ip){
        ip = checkIp(ip);
        String[] split = ip.trim().split("\\.");
        return ( s2l(split[0]) << 24 ) + ( s2l(split[1]) << 16 ) + ( s2l(split[2]) << 8 )+ ( s2l(split[3]) );
    }
    private static long s2l(String s){
        return Long.parseLong(s,10);
    }
    private static String checkIp(String ip){
        return Optional.ofNullable(ip).filter(s -> !s.isEmpty()&&s.matches(IP_REGEX))
                .orElseThrow(() -> new RuntimeException(ip + " ip地址不合法."));
    }
    private static String checkMask(String mask){
        return Optional.ofNullable(mask).filter(s -> !s.isEmpty()&&NET_MASK.containsValue(mask))
                .orElseThrow(() -> new RuntimeException( mask + "掩码不合法."));
    }
    public static class IpInf{
        /** ip */
        private final Inf ip;
        /** 掩码 */
        private final Inf mask;
        /** 网段 */
        private final Inf segment;
        /** 广播地址 */
        private final Inf broadcast;
        /** 开始ip */
        private final Inf startIp;
        /** 结束ip */
        private final Inf endIp;
        /** 可用ip数 */
        private final Long count;
        /**
         * 初始化
         * @param ip 如 192.168.1.1
         * @param mask 掩码 如 255.255.255.255
         */
        public IpInf(String ip,String mask){
            System.out.println("ip:"+ip+",mask:"+mask);
            this.ip = new Inf(checkIp(ip));
            this.mask = new Inf(checkMask(mask));
            //网段 = ip & 掩码
            this.segment = new Inf(this.ip.val & this.mask.val);
            // 广播地址 网段末尾用1补齐
            this.broadcast = new Inf(this.segment.val | (~this.mask.val & VALIDATE_DATA));
            // 开始地址 网段+1
            this.startIp = new Inf(this.segment.val + 1L);
            // 结束地址 广播地址-1
            this.endIp = new Inf(this.broadcast.val - 1L);
            this.count = this.endIp.val - this.startIp.val;
        }

        public Inf ip() { return ip; }
        public Inf mask() { return mask; }
        public Inf segment() { return segment; }
        public Inf broadcast() { return broadcast; }
        public Inf startIp() { return startIp; }
        public Inf endIp() { return endIp; }
        public Long count() { return count; }

        @Override
        public String toString() {
            return "{ip=" + ip + ", mask=" + mask + ", segment=" + segment + ", broadcast=" + broadcast
                    + ", startIp=" + startIp + ", endIp=" + endIp + ", count=" + count + '}';
        }
    }
    public static class Inf{
        private final String lab;
        private final Long val;
        Inf(String l){ this.lab = l;this.val = ip2Long(l); }
        Inf(Long v){ this.val = v;this.lab = long2ip(v); }
        public Long toLong() { return val; }
        public String toStr() { return lab; }

        @Override
        public String toString() {
            return "{str='" + lab + "', long=" + val + '}';
        }
    }
}

测试

本机ip:192.168.***.171
-------------
ip:192.168.1.2,mask:255.255.254.0
{ip={str='192.168.1.2', long=3232235778}, mask={str='255.255.254.0', long=4294966784}, segment={str='192.168.0.0', long=3232235520}, broadcast={str='192.168.1.255', long=3232236031}, startIp={str='192.168.0.1', long=3232235521}, endIp={str='192.168.1.254', long=3232236030}, count=509}
ip:192.168.1.3,mask:255.255.255.0
{ip={str='192.168.1.3', long=3232235779}, mask={str='255.255.255.0', long=4294967040}, segment={str='192.168.1.0', long=3232235776}, broadcast={str='192.168.1.255', long=3232236031}, startIp={str='192.168.1.1', long=3232235777}, endIp={str='192.168.1.254', long=3232236030}, count=253}
-------------
ip:10.10.10.116>>>168430196
ip:10.10.10.116,startIP:10.10.1.0,endIP:10.10.255.255,>>>true
-------------
ip:10.2.1.0,cip:10.2.0.0/17,>>>true

截图
在这里插入图片描述

END

代码仅供参考,请充分测试后在使用。谢谢Thanks♪(・ω・)ノ

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jdk8-获取本机ip、判断ip范围、ip与long互转等 的相关文章

  • CentOS8 使用yum 安装 jdk8

    原文地址 1 安装方法 CentOS8上使用 yum 直接安装 xff0c 环境变量自动配置好 2 查看是否已安装 看到下面结果 xff0c 说明已经安装配置 jdk 1 2 3 4 root 64 localhost java versi
  • 下载JDK8 JVM源码

    性子急的可以直接看快速下载步骤 xff1a 目录 详细步骤快速下载步骤 详细步骤 打开openJDK官网 xff1a https openjdk org 找到左侧的Mercurial xff0c 点击进入新界面 选择jdk8 xff0c 点
  • git Filename too long

    全局 git config global core longpaths true 当前仓库 git config core longpaths true 转载于 https www cnblogs com EasonJim p 108038
  • linux c++11 获取本机ip地址 ipv4

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • UI自动化之TouchAction(dirver).long_press()长按

    之前篇说过driver tap可以通过duration参数设置实现长按 xff0c 除外TouchAction也可以 xff0c 而且还可以用之实现多个点击的事件集 xff0c 废话不多说直接贴码 xff1a span class toke
  • SpringBoot项目启动报错:Command line is too long. Shorten command line for WebApplication...

    错误描述 spring工程启动时 xff0c 下方报错Error running 39 WebApplication 39 Command line is too long Shorten command line for WebAppli
  • ubuntu1804源码编译jdk8

    这里纯粹自己弄着玩 xff0c 因为以前没有成功过 xff0c 这里记录一下 xff0c 就是让遇到问题的人可以规避问题 xff0c 快速编译自己的jdk 相信很多学java的人都看过或者了解过一本书 深入理解java虚拟机 xff0c 里
  • switch语句作用在byte上却不能作用在String和long上

    在switch xff08 exprl xff09 语句中 xff0c exprl必须是一个整数表达式或者枚举常量 而byte short char都可以隐式转换为int类型 xff0c 整数表达式可以是int或者包装类Integer xf
  • centos7+jdk8+安装Elasticsearch6.0

    一 xff1a 为Elasticsearch准备用户 1 添加用户 Elasticsearch6 0需要使用非root用户启动 root 64 66 adduser ela root 64 66 passwd ela 2 授权用户 查看文件
  • windows enable long environment path

    windows gt gpedit msc gt enter Edit Group Policy gt Local Computer Policy gt Computer Configuration gt Administrative Te
  • (*((volatile unsigned long *) 0xE0028000)) 作用小解

    define IO0PIN volatile unsigned long 0xE0028000 no in lpc210x 以此句为例 简述如下 与51单片机的头文件 lt reg51 h gt 类似 在ARM处理器中 也必须有自己的寄存器
  • C语言中关于int、long int、long long 的区别

    1 关于int 和 long int xff08 1 xff09 在VC下没有区别 两种类型均用4个字节存放数据 xff08 2 xff09 VC是后出的编译器 xff0c 之前有很多早期的C编译器 xff0c 在早期编译器下long in
  • jdk8-获取本机ip、判断ip范围、ip与long互转等

    在配置nginx的ip白名单时候 xff0c 会通过ip段进行配置 xff08 如 10 10 10 10 24 xff09 就在思考这种配置怎么通过代码解析并判断 xff0c 故通过搜索网络内容 xff0c 并通过java编写测试代码 代
  • Java中 Long(long) 和Integer(int)之间的强制转换

    一 将long型转化为int型 这里的long型是基础类型 long a 10 int b int a 二 将Long型转换为int 型的 这里的Long型是包装类型 Long a 10 int b a intValue 三 将int型转化
  • JDK8新特性-Function接口与BiFunction接口

    Function 接口 JDK8新增的函数式接口 接口只有一个抽象方法apply 接受一个T类型参数 返回一个R类型参数 T R表示泛型 可以相同 除了一个抽象的apply方法之外 Function存在两个默认的default方法 comp
  • JDK8新特性详解Lambda、StreamAPI、Optional等

    JDK8学习笔记 学习视频地址 https www bilibili com video BV1k64y1R7sA 操作代码 https gitee com rederic study jdk8 git 一 JDK8新特性 1 Lambda
  • Java虚拟机:关于JDK8到JDK9-10的一点小变化(tools.jar、dt.jar)

    关于JDK8到JDK9 10的一点小变化 JDK在每一次版本升级中 或多或少都会有一些比较重要的变化 或许在你使用的过程中 你就很有可能遇到 一 Removed or Changed APIs JDK8在升级到9或者10的时候 有一些变化还
  • JDK8安装及系统变量配置(包含错误处理)

    jdk安装 一 下载JDK 二 安装 三 配置系统变量 四 可能遇到的问题 1 显示已经安装的问题 或者 读取注册表项值失败 2 原因 3 解决 五 验证安装成功 一 下载JDK JDK下载官网 二 安装 双击之后 一直下一步就ok 三 配
  • jdk13快来了,jdk8的这几点应该看看!

    说明 jdk8虽然出现很久了 但是可能我们还是有很多人并不太熟悉 本文主要就是介绍说明一些jdk8相关的内容 主要会讲解 lambda表达式 方法引用 默认方法 Stream 用Optional取代null 新的日志和时间 Completa
  • JDK 8 List集合使用记录

    JDK8 的新特性给我们开发带来了很大的便利性 先声明 我没有系统的去学习 JDK8的这些所有新特性 本文只是记录一些我个人日常开发中常遇到的一些 JDK8 的新特性方法 1 提取对象集合中的某一属性集合 List lt 对象 gt gt

随机推荐