【问题标题】:How can I convert a long to its binary 32 bit representation?如何将 long 转换为其二进制 32 位表示?
【发布时间】:2020-06-26 19:58:12
【问题描述】:

我正在做以下编程练习:int32 to IPv4。声明是:

获取以下 IPv4 地址:128.32.10.1

该地址有 4 个八位字节,其中每个八位字节是一个字节(或 8 位)。

1st octet 128 has the binary representation: 10000000
2nd octet 32 has the binary representation: 00100000
3rd octet 10 has the binary representation: 00001010
4th octet 1 has the binary representation: 00000001

所以 128.32.10.1 == 10000000.00100000.00001010.00000001

由于上面的IP地址有32位,我们可以将其表示为 无符号 32 位数:2149583361

完成接受无符号 32 位数字并返回的函数 其 IPv4 地址的字符串表示形式。例子

2149583361 ==> "128.32.10.1" 32 ==> "0.0.0.32" 0 ==> "0.0.0.0"

首先,我尝试了以下代码:

public class Kata {
    public static String longToIP(long ip) {
        System.out.println("ip: "+ip);
    String binary = Long.toBinaryString(ip);
    System.out.println("binary: "+binary);
    return String.format("%s.%s.%s.%s",Long.parseLong(binary.substring(0,8),2),Long.parseLong(binary.substring(8,16),2),
            Long.parseLong(binary.substring(16,24),2),Long.parseLong(binary.substring(24),2));
    }
}

作为测试:

import org.junit.Test;

import java.util.Random;

import static org.junit.Assert.assertEquals;

public class KataTest {
    @Test
    public void sampleTest() {
        assertEquals("128.114.17.104", Kata.longToIP(2154959208L));
        assertEquals("0.0.0.0", Kata.longToIP(0));
        assertEquals("128.32.10.1", Kata.longToIP(2149583361L));
    }
}

当输入为零时,我的代码抛出异常:java.lang.StringIndexOutOfBoundsException: begin 0, end 8, length 1 at Kata.longToIP(Kata.java:6)

由于在第 4 行,我从 long 转换为 string,二进制没有填充零:

ip: 0
binary: 0

如何将长 ip 值转换为始终为 32 位的二进制字符串(添加填充 0)?

我尝试了以下方法:

public class Kata {
    public static String longToIP(long ip) {
        System.out.println("ip: "+ip);
    String binary = String.format("%032d",Long.parseLong(Long.toBinaryString(ip)));
    System.out.println("binary: "+binary);
    return String.format("%s.%s.%s.%s",Long.parseLong(binary.substring(0,8),2),Long.parseLong(binary.substring(8,16),2),
            Long.parseLong(binary.substring(16,24),2),Long.parseLong(binary.substring(24),2));
    }
}

它会抛出java.lang.NumberFormatException: For input string: "10000000011100100001000101101000" at Kata.longToIP(Kata.java:4)

然后我改成:

public class Kata {
    public static String longToIP(long ip) {
        System.out.println("ip: "+ip);
    String binary = String.format("%032d",Long.parseLong(Long.toBinaryString(ip),2));
    System.out.println("binary: "+binary);
    return String.format("%s.%s.%s.%s",Long.parseLong(binary.substring(0,8),2),Long.parseLong(binary.substring(8,16),2),
            Long.parseLong(binary.substring(16,24),2),Long.parseLong(binary.substring(24),2));
    }
}

这也会引发异常:

java.lang.NumberFormatException: For input string: "00000021"
at Kata.longToIP(Kata.java:7)

我已阅读:

【问题讨论】:

  • int32 是 int 而不是 long

标签: java string casting binary long-integer


【解决方案1】:
public class Kata {
    public static String longToIP(long ip) {
        //1. translate the ip to binary representation
        String str = "";
        if (ip == 0) {
            str = ip + "";
        } else {
            while (ip != 0) {
                str = ip % 2 + str;
                ip = ip / 2;
            }
        }

        //2. if the binary string is shorter than 32 bit, then add "0" in front
        while (str.length() != 32) {
            str = "0" + str;
        }

        String result = "";

        //3. truncate the str to four items
        for (int i = 0; i < 4; i++) {
            String partStr = str.substring(i * 8, 8 * (i + 1));

            //4. translate every item to decimal number
            int bi = Integer.parseInt(partStr, 2);
            if (i == 3) {
                result += bi + "";
            } else {
                result += bi + ".";
            }
        }
        return result;
    }
}

【讨论】:

    【解决方案2】:

    我们可以添加填充零:

    public class Kata {
        public static String longToIP(long ip) {
            System.out.println("ip: "+ip);
        String binary = Long.toBinaryString(ip);
        if(binary.length()<32) binary = "0".repeat(32-binary.length()) + binary;
        System.out.println("binary: "+binary);
        return String.format("%s.%s.%s.%s",Long.parseLong(binary.substring(0,8),2),Long.parseLong(binary.substring(8,16),2),
                Long.parseLong(binary.substring(16,24),2),Long.parseLong(binary.substring(24),2));
        }
    }
    

    或者,我们可以在将长字符串转换为二进制字符串的同一句子中使用格式(基于Jeff Scott Brown 对本主题的回答Converting long to binary in Java gives 31 bits?

    public class Kata {
        public static String longToIP(long ip) {
            System.out.println("ip: "+ip);
        String binary = String.format("%32s",Long.toBinaryString(ip)).replace(' ','0'); 
        System.out.println("binary: "+binary);
        return String.format("%s.%s.%s.%s",Long.parseLong(binary.substring(0,8),2),Long.parseLong(binary.substring(8,16),2),
                Long.parseLong(binary.substring(16,24),2),Long.parseLong(binary.substring(24),2));
        }
    }
    

    另外我们可以使用网络 java 库(Angelwrith 解决方案):

    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class Kata {
      public static String longToIP(long ip) {
        try {
             return InetAddress.getByName(String.valueOf(ip)).getHostAddress();
            } catch (UnknownHostException e) {
             e.printStackTrace();
             return null;
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      要将 int 值转换为标准的点分四边形格式,这将起作用。通过减少 8 的值并附加适当的字符串,将值从左侧移动是一件简单的事情。

          public static String toIP(int x) {
              String ip = Integer.toString((int) (x >> 24 & 0xFF)) + ".";
              ip += Integer.toString((int) ((x >> 16) & 0xFF)) + ".";
              ip += Integer.toString((int) ((x >> 8) & 0xFF)) + ".";
              ip += Integer.toString((int) (x & 0xFF));
              return ip;
          }
      
      

      要将 int 转换为长度为 32 的填充二进制值,请尝试以下操作。它确保传递的 int 转换为 33 位值,因此标准 Long.toBinaryString 方法将返回 33 个字符的值。第一个字符被扔掉了,因为它已经达到了它的目的。

          public static String toPaddedBinary(int v) {
              long x = (v|(1L<<32))&0x1FFFFFFFFL;
              return Long.toBinaryString(x).substring(1);
          }
      

      以下代码显示了输出。

              int [] data = {32, 1233, Integer.MAX_VALUE, Integer.MIN_VALUE, 192<<24|156<<16|5};
              for (int d : data) {
                  System.out.println(toIP(d));
                  System.out.println(toPaddedBinary(d));
                  System.out.println();
              }
      

      打印

      0.0.0.32
      00000000000000000000000000100000
      
      0.0.4.209
      00000000000000000000010011010001
      
      127.255.255.255
      01111111111111111111111111111111
      
      128.0.0.0
      10000000000000000000000000000000
      
      192.156.0.5
      11000000100111000000000000000101
      
      
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-26
        • 2017-08-18
        • 1970-01-01
        • 2016-10-12
        • 2018-11-25
        相关资源
        最近更新 更多