整数与ip地址及子网掩码间的转换

题目是
输入:一个整数n和一个4~30之间的正整数m,使用n来初始化IP地址(IP地址的二进制表示和n一摸一样),使用m来初始化子网掩码,m代表子网掩码中1的个数
输出:分别输出IP地址、子网掩码的点分十进制形式
测试类如下

import java.util.Scanner;
public class IPAddrText {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n, m;
        n = input.nextInt();
        m = input.nextInt();
        IPAddr ip = new IPAddr(n, m);
        ip.showIP();
        ip.showIPInfo(); 
        input.close();
    }
}

我写的是这样的(不知道IPInfo是什么了,默认它为子网掩码吧)

public class IPAddr {
    private String ip="";
    private String IPInfo ="";

    public IPAddr(int n, int m){
        String ip = Integer.toHexString(n);
        this.ip = Integer.valueOf(ip.substring(0, 1), 16).toString() + ".";
        this.ip += Integer.valueOf(ip.substring(2, 3), 16).toString() + ".";
        this.ip += Integer.valueOf(ip.substring(4, 5), 16).toString() + ".";
        this.ip += Integer.valueOf(ip.substring(6, 7), 16).toString();

        String IPInfo = "";
        for(int i = 0; i < 32; i++){
            if(i < m)
                IPInfo += "1";
            else
                IPInfo += "0";
        }

        this.IPInfo = Integer.valueOf(IPInfo.substring(0, 7), 2).toString() + ".";
        this.IPInfo += Integer.valueOf(IPInfo.substring(8, 15), 2).toString() + ".";
        this.IPInfo += Integer.valueOf(IPInfo.substring(16, 23), 2).toString() + ".";
        this.IPInfo += Integer.valueOf(IPInfo.substring(24, 31), 2).toString();
    }
    public void showIP(){
        System.out.println(ip);
    }
    public void showIPInfo(){
        System.out.println(IPInfo);
    }
}

怎么写都不对,请各位大 佬帮我看看问题出在哪

可以先定义一个 IPAddr 类来处理 IP 地址和子网掩码相关的操作,参考:

import java.util.Arrays;

public class IPAddr {
    private int[] ip = new int[4];  // IP 地址
    private int[] mask = new int[4];  // 子网掩码

    public IPAddr(int n, int m) {
        // 初始化 IP 地址和子网掩码
        for (int i = 0; i < 4; i++) {
            ip[i] = (n >> (8 * (3 - i))) & 255;  // 取出每个字节并转换为十进制数
            mask[i] = i < m / 8 ? 255 : (i == m / 8 ? (int)(Math.pow(2, m % 8)) - 1 : 0);
        }
    }

    public void showIP() {
        // 输出 IP 地址的点分十进制形式
        System.out.println(Arrays.toString(ip).replaceAll("[\\[\\]\\,]", ""));
    }

    public void showIPInfo() {
        // 输出子网掩码的点分十进制形式,并计算 IP 地址的网络地址和主机地址
        int[] network = new int[4];
        int[] host = new int[4];

        for (int i = 0; i < 4; i++) {
            network[i] = ip[i] & mask[i];
            host[i] = ip[i] & ~mask[i];
        }

        System.out.println(Arrays.toString(mask).replaceAll("[\\[\\]\\,]", ""));
        System.out.println(Arrays.toString(network).replaceAll("[\\[\\]\\,]", ""));
        System.out.println(Arrays.toString(host).replaceAll("[\\[\\]\\,]", ""));
    }
}


例如输入:-1455049865 24
输出为:169.69.179.119
             255.255.255.0


  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7682498
  • 这篇博客也不错, 你可以看下IP划分子网的实训案例:某单位申请了一个IP为218.197.17.0,该单位需要建设四个网络,分别用于管理四个部门,要求分配各主机数量相同,试对该单位进行规划并配置。
  • 除此之外, 这篇博客: IP地址、子网掩码、有效子网数、有效主机数中的 3. 利用子网掩码计算最大可用主机数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • A类IP地址,子网掩码为255.252.0.0,将它划分成若干子网络,每个子网络中可用主机数有多少?

    ①  将子网掩码转换成二进制表示11111111.11111100.00000000.00000000

    ②    统计一下它的主机位共有18位

    ③    最大可用主机数就是2的18次方减2(除去全是0的网络地址和全是1广播地址),即每个子网络最多有262142台主机可用。

  • 以下回答由chatgpt基于相关博客总结生成:

    这道问题需要实现两种功能:

    1. 用整数n和正整数m初始化IP地址和子网掩码,最终输出点分十进制形式
    2. 判断一个字符串是否为合法的IP地址

    下面分别给出两种功能的解决方案:

    1. 用整数n和正整数m初始化IP地址和子网掩码

    ip地址由4个8位二进制数组成,可以将整数n转化为4个8位二进制数来表示IP地址。子网掩码中1的个数m可以表示为一个32位的二进制数的前m位都是1,后32-m位都是0。实现方式如下:

    public static String getIPAddress(int n, int m) {
        // 将整数n转化为4个8位二进制数作为IP地址的四个部分
        String[] ip = new String[4];
        for (int i = 0; i < 4; i++) {
            ip[i] = String.valueOf(n & 255);
            n >>= 8;
        }
        // 将32位的二进制数转化为子网掩码
        int mask = ((1 << m) - 1) << (32 - m);
        String[] subnetMask = new String[4];
        for (int i = 0; i < 4; i++) {
            subnetMask[i] = String.valueOf((mask >> (i * 8)) & 255);
        }
        // 输出点分十进制形式的IP地址和子网掩码
        return String.join(".", ip) + " & " + String.join(".", subnetMask);
    }
    

    其中,使用位运算右移来获取整数n的每个8位二进制数部分,使用位运算左移和按位与运算来获取子网掩码的每个8位二进制数部分,最终使用join方法拼接成点分十进制形式。

    示例输出:

    System.out.println(getIPAddress(16843009, 24));  // 输出结果为:1.0.0.1 & 255.255.255.0
    

    2. 判断一个字符串是否为合法的IP地址

    判断一个字符串是否为IP地址需要满足以下要求:

    1. 字符串长度在7-15之间
    2. 字符串包含四个由数字组成的部分,每个部分的数字在0-255之间

    实现方式如下:

    public static boolean isIPAddress(String str) {
        // 字符串长度在7-15之间
        if (str.length() < 7 || str.length() > 15) {
            return false;
        }
        String[] parts = str.split("\\.");
        // 字符串包含四个由数字组成的部分
        if (parts.length != 4) {
            return false;
        }
        for (String part : parts) {
            try {
                // 每个部分的数字在0-255之间
                int num = Integer.parseInt(part);
                if (num < 0 || num > 255) {
                    return false;
                }
            } catch (NumberFormatException e) {
                return false;
            }
        }
        return true;
    }
    

    其中,使用split方法将字符串按照小数点分隔成4个部分,使用parseInt方法将每个部分转化为整数,如果有部分不满足要求,则返回false,否则返回true。

    示例输出:

    System.out.println(isIPAddress("192.168.0.1"));  // 输出结果为:true
    System.out.println(isIPAddress("192.168.0.256"));  // 输出结果为:false