JAVA根据ip地址和子网掩码获取子网地址

最近遇到一个需求,根据IPV4/IPV6和子网掩码获取对应的子网地址,根据计算逻辑,自己简单实现了一版算法,如有问题,欢迎指出!

/**
 * 根据IP地址和子网掩码获取子网段
 * 转换规则
 * 一个主机的IP地址是202.112.14.137
 * 子网掩码是255.255.255.224 分别转换为二进制 maskBit 位数,如果是12,即开头12个1,后面补0,补足位数
 * 11001010 01110000 00001110 10001001
 * 11111111 11111111 11111111 11100000
 * 进行与的运算,即乘法运算:11001010 01110000 00001110 100 00000
 * 然后再转换为对应的ip地址进制数即 202.112.14.128
 * @author wjj
 * @param ipType ip类型 IPV4/IPV6 ip 要计算的ip  maskBit 子网掩码  例如32
 * @date 2022.11.16
 * */
public static String getSubnet(String ipType, String ip, Integer maskBit) {
    // 最终的子网地址
    StringBuilder builder = new StringBuilder();
    // 1- IPV4的处理
    if ("IPV4".equals(ipType)) {
        // 1.1- 将IPV4根据.分割,转换成数组
        String[] ipV4Array = ip.split("\\.");
        // 1.2- 只有正确的ip地址才进行计算
        if (ipV4Array.length == 4) {
            // 1.3 将分割后的每组数据与子网掩码进行与的运算,得到每组的子网地址
            for (String number : ipV4Array) {
                // 1.4 够八位的话就是八个1
                if (maskBit >= 8) {
                    // 1.5 如果掩码全是1,不用做与的计算,地址不变
                    if (StringUtils.isBlank(builder.toString())) {
                        builder.append(number);
                    } else {
                        builder.append(".").append(number);
                    }
                    maskBit = maskBit - 8;
                } else {
                    // 1.6 不够八位的话,后面补0补足八位,进行与的运算
                    if (maskBit > 0) {
                        StringBuilder mask = new StringBuilder();
                        for (int i = 0; i < maskBit; i++) {
                            mask.append(1);
                        }
                        for (int i = 0; i < 8 - maskBit; i++) {
                            mask.append(0);
                        }
                        String conversion = ConversionOfNumberUtils.conversion(mask.toString(), 2, 10);
                        Long subnetNumber = Long.parseLong(number) & Long.parseLong(conversion);
                        builder.append(".").append(subnetNumber);
                        maskBit = 0;
                    } else {
                        // 1.7 全是0的话,不用作与的计算,地址直接是0
                        builder.append(".").append(0);
                    }
                }
            }
        }
    } else if ("IPV6".equals(ipType)) {
        // 2- IPV6的处理 fe80::ed14:23f6:b8c8:cff6  IPV6 128位 每:代表 16位 ::连续冒号代表的中间是0,无需处理
        // 2.1 将IPV6根据:分割,转换为数据进行处理
        String[] ipV6Array = ip.split(":");
        if (ipV6Array.length > 0) {
            // 2.2 将数组中的每个元素进行处理
            for (String number : ipV6Array) {
                if (maskBit >= 16) {
                    // 2.3 :: 的处理,计算出来包含了多少位
                    if (StringUtils.isBlank(number)) {
                        // : 隐掉了几组数据
                        Integer num = 8 - ipV6Array.length + 1;
                        maskBit = maskBit - 16 * num;
                        builder.append(":");
                    } else {
                        // 2.4 掩码全是1,不用做与的计算,地址不变
                        if (StringUtils.isBlank(builder.toString())) {
                            builder.append(number);
                        } else {
                            builder.append(":").append(number);
                        }
                        maskBit = maskBit - 16;
                    }
                } else {
                    // 2.5 不够十六位的话,补足十六位,进行与的计算
                    if (maskBit > 0) {
                        StringBuilder mask = new StringBuilder();
                        for (int i = 0; i < maskBit; i++) {
                            mask.append(1);
                        }
                        for (int i = 0; i < 16 - maskBit; i++) {
                            mask.append(0);
                        }
                        // 将当前组的地址和掩码分别转为为10进制进行与的计算
                        String conversionMask = ConversionOfNumberUtils.conversion(mask.toString(), 2, 10);
                        String conversionAddress = ConversionOfNumberUtils.conversion(number, 16, 10);
                        Long subnetNumber = Long.parseLong(conversionMask) & Long.parseLong(conversionAddress);
                        // 将计算后的10进行转换为16进制ipV6地址
                        String conversionIpV6Address = ConversionOfNumberUtils.conversion(subnetNumber.toString(), 10, 16);
                        builder.append(":").append(conversionIpV6Address);
                        maskBit = 0;
                    } else {
                        // 1.7 全是0的话,不用作与的计算,地址直接是0
                        builder.append(":").append(0);
                    }
                }
            }
        }
    }
    return builder.toString();
}

其中进制转换工具类

import java.math.BigInteger;

/**
 * 进制转换工具类
 * @author wjj
 * @date 2022.11.17
 * */
public class ConversionOfNumberUtils {

    /**
     * 将任意进制的数转换为其他进制
     * @param number 要转换的进制数 beforeRadix 转换前的进制数 afterRadix 转换后的进制数
     * @author 吴军杰
     * @date 2022.11.17
     * */
    public static String conversion(String number, Integer beforeRadix, Integer afterRadix) {
        BigInteger integer = new BigInteger(number, beforeRadix);
        return integer.toString(afterRadix);
    }
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要根据子网掩码IP地址获取广播地址,可以通过Java编写一个方法来实现。方法的输入参数为子网掩码IP地址,输出结果为广播地址。 首先,需要将子网掩码IP地址转换为二进制形式。可以使用Java的位运算符来实现。 接下来,通过按位逻辑与操作,将IP地址子网掩码进行逐位比较,得到网络地址。网络地址IP地址的网络部分和子网掩码确定。 然后,对网络地址中的主机位进行取反操作,得到反码。反码中的主机部分全为1,用于表示广播地址的主机部分。 最后,将网络地址和反码进行按位逻辑或操作,即可得到广播地址。 下面是一个示例代码实现: ``` public class BroadcastAddressCalculator { public static String calculateBroadcastAddress(String subnetMask, String ipAddress) { // 将子网掩码IP地址转换为二进制 String binarySubnetMask = convertToBinary(subnetMask); String binaryIpAddress = convertToBinary(ipAddress); // 按位逻辑与操作,得到网络地址 String networkAddress = bitwiseAnd(binarySubnetMask, binaryIpAddress); // 对网络地址的主机位进行取反操作,得到反码,即广播地址的主机部分 String hostPart = bitwiseNot(networkAddress); // 将网络地址和反码进行按位逻辑或操作,得到广播地址 String broadcastAddress = bitwiseOr(networkAddress, hostPart); // 将二进制形式的广播地址转换为十进制形式 String decimalBroadcastAddress = convertToDecimal(broadcastAddress); return decimalBroadcastAddress; } // 将十进制IP地址转换为二进制形式 private static String convertToBinary(String ipAddress) { // 实现方式略,可以使用Java的位运算符来逐位转换 } // 按位逻辑与操作 private static String bitwiseAnd(String binarySubnetMask, String binaryIpAddress) { // 实现方式略,可以使用Java的位运算符实现逐位与操作 } // 按位逻辑或操作 private static String bitwiseOr(String binaryNetworkAddress, String binaryHostPart) { // 实现方式略,可以使用Java的位运算符实现逐位或操作 } // 对二进制字符串进行按位取反操作 private static String bitwiseNot(String binaryString) { // 实现方式略,可以使用Java的位运算符实现逐位取反操作 } // 将二进制形式的广播地址转换为十进制形式 private static String convertToDecimal(String broadcastAddress) { // 实现方式略,可以使用Java的位运算符来逐位转换 } } ``` 使用该方法,传入合法的子网掩码IP地址,即可获取到对应的广播地址
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值