CIDR网络地址、广播地址、网段区间计算说明与计算工具

文章目录

  • 开始
  • 问题
    • 参考答案
  • 答案解析
  • 计算工具
  • 测试

开始

好久没有看计算网络,感觉已经完全返给老师了。

最近,有同事遇到个问题,网络一直不对,又开始重新看一下。

相信很多朋友长时间不看也忘了,所以,这里记录一下,并提供了一个工具类用来计算相关值。

希望帮助新学习的朋友学习、已经忘了的朋友重新回忆。

觉得自己理解到位的朋友,可以尝试一下下面的问题。

问题

我的IPv4地址是:172.17.1.6,子网掩码是:255.255.252.0

请问:

  1. 我和172.17.0.6在同一网段吗?172.17.2.6呢?172.17.3.6呢?172.17.4.6呢?
  2. 我所在网络的网络地址是多少?网络位数是多少?
  3. 我所在网络的广播地址是多少?
  4. 我所在网络的最小主机IP地址是多少?
  5. 我所在的网络最大主机IP地址是多少?

上面的问题你能回答几个?答对了几个?

参考答案

  1. 172.17.1.6和172.17.0.6、172.17.2.6、172.17.3.6是同一网段,和172.17.4.6不是同一网段
  2. 我所在网络的网络地址:10101100000100010000000000000000(172.17.0.0/22)
  3. 我所在网络的广播地址:10101100000100010000001111111111(172.17.3.255)
  4. 我所在网络的最小主机IP地址:10101100000100010000000000000001(172.17.0.1)
  5. 我所在的网络最大主机IP地址:10101100000100010000001111111110(172.17.3.254)

答案解析

首先算网络地址:
我的IP & 子网掩码就是我所在的网络地址:
我的地址:10101100000100010000000100000110(172.17.1.6)
子网掩码:11111111111111111111110000000000(255.255.252.0)
与有0为0:10101100000100010000000000000000(172.17.0.0)

网络位数,数子网掩码前面1的个数:22,因此网络号可以写成:172.17.0.0/22,很多网策支持这样配置。

广播地址是主机位全为1的地址,因此把网络地址中的主机位全换为1即可:
网络位数是22,所以主机位是10位:10101100000100010000001111111111(172.17.3.255)

最小的主机地址是网络地址+1:10101100000100010000000000000001(172.17.0.1)
最大的主机地址是广播地址-1:10101100000100010000001111111110(172.17.3.254)

有了最小的主机地址和最大的主机地址,现在再看第一个问题,是不是清晰了。

这其中最大的误区就是,一晃眼就认为172.17.1.6的网段是172.17.1.0
这是没有CIDR,在子网掩码为:255.255.255.0时才成立

计算工具

package vip.meet.network.ip;

import lombok.extern.slf4j.Slf4j;

import java.math.BigInteger;

/**
 * CIDR
 * 网络中:
 * 全为0的是:网络地址(最小地址)
 * 全为1的是:广播地址(最大地址)
 * 最小可用地址=网络地址+1
 * 最大可用地址=广播地址-1
 * <p>
 * 私有地址:
 * A类地址范围:10.0.0-10.255.255.255
 * B类地址范围:172.16.0.0-172.31.255.555
 * C类地址范围:192.168.0.0-192.168.255.255
 */
@Slf4j
public class IpCalculateHelper {

    /**
     * 根据主机IP和子网掩码计算网络地址 ip & mask
     * <p>
     * 198.1.33.205 :11000110000000010010000111001101
     * 255.255.252.0:11111111111111111111110000000000
     * &
     * 198.1.32.0/22:11000110000000010010000000000000
     *
     * @param netIp 要计算的ip 198.1.33.205
     * @param mask  子网掩码 255.255.252.0
     * @return 网络地址 198.1.32.0
     */
    public static String getIPV4CIDRNet(String netIp, String mask) {
        String ipv4CIDRBinary = getIPV4CIDRBinary(netIp, mask);
        return binaryIp2NetIp(ipv4CIDRBinary);
    }

    /**
     * 获取网络二进制地址
     *
     * @param netIp 198.1.33.205
     * @param mask  55.255.252.0
     * @return 11000110000000010010000000000000
     */
    public static String getIPV4CIDRBinary(String netIp, String mask) {
        BigInteger ipBin = new BigInteger(getIPBinary(netIp), 2);
        BigInteger maskBin = new BigInteger(getIPBinary(mask), 2);
        BigInteger result = ipBin.and(maskBin);
        String string = result.toString(2);
        return "0".repeat(32 - string.length()) + string;
    }

    /**
     * 二进制转ip转网络ip
     *
     * @param binaryIp 二进制ip 11000110000000010010000000000000
     * @return ip 198.1.32.0
     */
    public static String binaryIp2NetIp(String binaryIp) {
        int length = binaryIp.length();
        if (length > 32) {
            throw new RuntimeException("非法ip长度:" + binaryIp);
        }
        String pad = "0".repeat(32 - length) + binaryIp;
        return Integer.valueOf(pad.substring(0, 8), 2) + "." +
                Integer.valueOf(pad.substring(8, 16), 2) + "." +
                Integer.valueOf(pad.substring(16, 24), 2) + "." +
                Integer.valueOf(pad.substring(24), 2);
    }

    /**
     * 二进制ip转ip
     *
     * @param netIp 198.1.32.0
     * @return binary ip 二进制ip 11000110000000010010000000000000
     */
    public static String getIPBinary(String netIp) {
        String[] parts = netIp.split("\\.");
        if (parts.length != 4) {
            throw new RuntimeException("非法ipv4:" + netIp);
        }
        StringBuilder sb = new StringBuilder();
        for (String part : parts) {
            BigInteger integer = new BigInteger(part, 10);
            String partIp = integer.toString(2);
            sb.append("0".repeat(8 - partIp.length())).append(partIp);
        }
        return sb.toString();
    }

    /**
     * 根据子网掩码算网络位数
     *
     * @param mask 子网掩码 255.255.252.0
     * @return 网络位数 22
     */
    public static int getNetBitFromMask(String mask) {
        String binString = getIPBinary(mask);
        int count = 0;
        for (int i = 0; i < binString.length(); i++) {
            if (binString.charAt(i) != '1') {
                break;
            }
            count++;
        }
        return count;
    }

    /**
     * 获取二进制子网掩码
     *
     * @param netBit 网络位数
     * @return 二进制子网掩码
     */
    public static String getMaskBinaryFromNetBit(int netBit) {
        if (netBit < 1 || netBit >= 32) {
            throw new RuntimeException("非法网络位数:" + netBit);
        }
        return "1".repeat(netBit) + "0".repeat(32 - netBit);
    }

    /**
     * 获取子网掩码
     *
     * @param netBit 网络位数
     * @return 子网掩码
     */
    public static String getMaskFromNetBit(int netBit) {
        if (netBit < 1 || netBit >= 32) {
            throw new RuntimeException("非法网络位数:" + netBit);
        }
        String maskBinary = "1".repeat(netBit) + "0".repeat(32 - netBit);
        return binaryIp2NetIp(maskBinary);
    }

    /**
     * 获取广播地址
     *
     * @param binaryCIDR cidr网络 11000110000000010010000000000000
     * @param netBit     网络位数 22
     * @return 广播地址 11000110000000010010001111111111
     */
    public static String getBroadcast(String binaryCIDR, int netBit) {
        if (netBit < 1 || netBit >= 32) {
            throw new RuntimeException("非法网络位数:" + netBit);
        }
        return binaryCIDR.substring(0, netBit) + "1".repeat(32 - netBit);
    }

    /**
     * 计算最小主机地址
     *
     * @param binaryCIDR CIDR网络地址 11000110000000010010000000000000
     * @return 最小主机地址 1100011000000001001000000000000
     */
    public static String minHostIp(String binaryCIDR) {
        return binaryCIDR.substring(0, 31) + "1";
    }

    /**
     * 最大主机地址
     *
     * @param binaryCIDR CIDR网络地址 11000110000000010010000000000000
     * @param netBit     网络位数 22
     * @return 最大主机地址 11000110000000010010001111111110
     */
    public static String maxHostIp(String binaryCIDR, int netBit) {
        if (netBit < 1 || netBit >= 32) {
            throw new RuntimeException("非法网络位数:" + netBit);
        }
        return binaryCIDR.substring(0, netBit) + "1".repeat(31 - netBit) + "0";
    }

    public static void printNetInfo(String netIp, int netBit) {
        if (netBit < 1 || netBit >= 32) {
            throw new RuntimeException("非法网络位数:" + netBit);
        }
        String mask = getMaskFromNetBit(netBit);
        printNetInfo(netIp, netBit, mask);
    }

    public static void printNetInfo(String netIp, String mask) {
        int netBit = getNetBitFromMask(mask);
        printNetInfo(netIp, netBit, mask);
    }

    public static void printNetInfo(String netIp, Integer netBit, String mask) {
        if (netBit == null) {
            netBit = getNetBitFromMask(mask);
        }
        if (netBit < 1 || netBit >= 32) {
            throw new RuntimeException("非法网络位数:" + netBit);
        }
        String ipBinary = getIPBinary(netIp);
        System.out.printf("二进制IP:%s(%s)\n", ipBinary, netIp);
        String maskBinary = getIPBinary(mask);
        System.out.printf("  掩码IP:%s(%s)\n", maskBinary, mask);
        String ipv4CIDRBinary = getIPV4CIDRBinary(netIp, mask);
        System.out.printf("  网络IP:%s(%s/%d)\n", ipv4CIDRBinary,
                binaryIp2NetIp(ipv4CIDRBinary), netBit);
        String broadcast = getBroadcast(ipv4CIDRBinary, netBit);
        System.out.printf("  广播IP:%s(%s)\n", broadcast, binaryIp2NetIp(broadcast));

        String min = minHostIp(ipv4CIDRBinary);
        System.out.printf(" 最小HIP:%s(%s)\n", min, binaryIp2NetIp(min));

        String max = maxHostIp(ipv4CIDRBinary, netBit);
        System.out.printf(" 最大HIP:%s(%s)\n", max, binaryIp2NetIp(max));
    }
}

测试

 @Test
public void printNetInfo() {
    IpCalculateHelper.printNetInfo("10.2.2.7", 20);
    System.out.println("--------------");
    IpCalculateHelper.printNetInfo("172.17.1.6", "255.255.252.0");
    System.out.println("--------------");
    IpCalculateHelper.printNetInfo("192.168.3.3", 21);
}

计算结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/460629.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UG NX二次开发(C#)-单选对话框UF_UI_select_with_single_dialog的使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、UF_UI_select_with_single_dialog函数3、实现代码3.1 利用委托创建一个方法3.2 直接调用1、前言 对于单选对话框,采用C++/C写的时候比较容易,也在帮助文档中有示例,但是对于C#开发采…

STL库中的string

文章目录 一、STL的六大组件二、string类2.1string中的size()方法2.2隐式类型的转换2.3string的多种构造2.4string中size与length是否有差异&#xff1f;2.4string中的capacity2.5string中的push_back和append2.6string中运算符重载operator2.7string中的reserve扩容2.8string中…

DJI RONIN 4D变0字节恢复案例

RONIN 4D这个产品听起来比较陌生&#xff0c;还是DJI大疆出品。没错&#xff0c;这是大疆进军影视级的重点明星机型。前阵子刚处理过大疆RONIN 4D的修复案例&#xff0c;下边这个案例是和exfat有关的老问题:文件长度变成0字节。 故障存储:希捷18T /MS Exfat文件系统。 故障现…

Mac上使用M1或M2芯片的设备安装Node.js时遇到一些问题,比如卡顿或性能问题

对于Mac上使用M1或M2芯片的设备可能会遇到在安装Node.js时遇到一些问题&#xff0c;比如卡顿或性能问题。这可能是因为某些软件包或工具在M1或M2芯片上的兼容性不佳。为了解决这个问题&#xff0c;您可以尝试以下方法&#xff1a; 1. 使用Rosetta模式 对于一些尚未适配M1或M2…

vscode 运行 java 项目之解决“Build failed, do you want to continue”的问题

Visual Studio Code运行 java 起来似乎比 IDEA 更轻量、比 eclipse 更友好&#xff0c;是不可多得的现代编译法宝。 安装好官方推荐的 java 扩展包后&#xff0c;就可以运行 java 代码了。功能 比 code runner 强&#xff0c;支持 gradle、maven、普通java项目&#xff0c;运行…

第五十九回 公孙胜芒砀山降魔 晁天王曾头市中箭-飞桨自然语言处理套件PaddleNLP初探

公孙胜献出八卦阵&#xff0c;宋江用八员大将守阵。项充李衮进入阵里&#xff0c;被抓住了。宋江说久闻大名&#xff0c;来梁山吧。两人说誓当效力到死&#xff0c;希望能先放我们两个回去把樊瑞带来一起。见到樊瑞后把宋江讲义气一说&#xff0c;樊瑞说不可逆天&#xff0c;于…

python flask报错OSError: [WinError 10038] 在一个非套接字上尝试了一个操作。

根本原因&#xff1a; 在执行到某个代码的时候&#xff0c;出错了&#xff0c;这个服务器的连接崩了&#xff0c;导致连接提前关闭。 针对的情况&#xff1a; 检查一下这个中文的报错的下面有没有这行 “ * Restarting with watchdog (windowsapi)” 上面某个地方应该还有这行…

HTML_CSS练习:HTML注释

一、代码示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>HTML注释</title> </head> <body><marquee loop"1">马龙强<!--下面的输入框是可以滚动的&#x…

黑马微服务p30踩坑

报错详情 : orderservice开不起来 : 发生报错 : 然后检查了以下端口啥的 &#xff0c;配置啥的都是没有问题的 ; 解决办法 : 1 . 修改nacos1,2,3中的端口&#xff0c;将conf 中 cluster.conf中 的 127.0.0.1 全部改成自己本机的真实ipv4地址; 本机真实ipv4地址查看 :…

云原生(二)、Docker基础

Docker Docker 是一种开源的容器化平台&#xff0c;用于开发、部署和运行应用程序。它允许开发者将应用程序及其所有依赖项打包到一个可移植的容器中&#xff0c;这个容器可以在任何支持 Docker 的环境中运行&#xff0c;无论是开发人员的个人笔记本电脑、测试环境、生产服务器…

Docker使用(三)Docker底层分析

Docker使用(三)Docker底层分析 四、底层分析 1、Docker镜像原理 1.1 commit镜像 docker commit 提交容器成为一个新的副本 # 命令和git原理类似 docker commit -m“提交的描述信息” -a“作者” 容器id 目标镜像名:[TAG] 实操&#xff1a; # 1、启动一个默认tomcat # …

【目标检测-数据集准备】DIOR转为yolo训练所需格式

【目标检测】DIOR遥感影像数据集&#xff0c;转为yolo系列模型训练所需格式。 标签文件位于Annotations下&#xff0c;格式为xml&#xff0c;yolo系列模型训练所需格式为txt&#xff0c;格式为 class_id x_center,y_center,w,h其中&#xff0c;train&#xff0c;text&#xff…

数据结构 之 队列(Queue)

​​​​​​​ &#x1f389;欢迎大家观看AUGENSTERN_dc的文章(o゜▽゜)o☆✨✨ &#x1f389;感谢各位读者在百忙之中抽出时间来垂阅我的文章&#xff0c;我会尽我所能向的大家分享我的知识和经验&#x1f4d6; &#x1f389;希望我们在一篇篇的文章中能够共同进步&#xff0…

数据结构知识点汇总(持续更新版)

数据结构 一、绪论 检测知识&#xff1a; 1.1基本概念 以前的计算机 弹道计算机 现如今 主要运用于非数值的计算 基本概念和术语 数据&#xff1a;是信息的载体&#xff0c;描述客观事物属性的值&#xff0c;字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的…

vite打包流程和原理

文章目录 打包原理Vite比Webpack快&#xff1f;在生产环境下的表现启动项目后&#xff0c;完成加载比较慢&#xff1f;Esbuild & Rollup热更新 打包原理 vite利用了ES module这个特性&#xff0c;使用vite运行项目时&#xff0c;首先会用esbuild进行预构建&#xff0c;将所…

Java 根据IP获取IP地址信息(离线)

<!-- https://mvnrepository.com/artifact/org.lionsoul/ip2region --><dependency><groupId>org.lionsoul</groupId><artifactId>ip2region</artifactId><version>2.7.0</version></dependency> 地址&#xff1a;http…

影响交易收益的因素有哪些?

在尝试做交易时&#xff0c;你可能会问自己一个问题&#xff1a;交易一天能赚多少钱&#xff1f;“如果我全职投入交易&#xff0c;一天能赚多少&#xff1f;”或者更广泛地说&#xff0c;“交易能为我带来怎样的财富&#xff1f;”这些问题本质上都充满了不确定性&#xff0c;…

PCM和I2S区别

I2S和PCM接口都是数字音频接口&#xff0c;而所见的蓝牙到cpu以及codec的音频接口都是用PCM接口&#xff0c;是不是两个接口有各自不同的应用呢&#xff1f;先来看下概念。 PCM&#xff08;PCM-clock、PCM-sync、PCM-in、PCM-out&#xff09;脉冲编码调制&#xff0c;模拟语音信…

力扣L12--- 125验证回文串(java版)-2024年3月15日

1.题目 2.知识点 注1&#xff1a;在 Java 中&#xff0c;toString() 方法用于将对象转换为字符串表示形式。对于数组对象&#xff0c;toString() 方法将返回数组的字符串表示形式&#xff0c;其中包含数组中每个元素的字符串表示形式&#xff0c;以逗号分隔&#xff0c;并且包…

使用IDEA2023创建传统的JavaWeb项目并运行与调试

日期:2024-0312 作者:dusuanyun 文档环境说明: OS:Deepin 20.9(Linux) JDK: OpenJDK21 Tomcat:10.1.19 IDEA: 2023.3.4 (Ultimate Edition) 本文档默认已经安装JDK及环境变量的配置。 关键词…