如何将一个长整型转换为其32位二进制表示?

huangapple go评论78阅读模式
英文:

How can I convert a long to its binary 32 bit representation?

问题

以下是翻译好的内容:

我正在进行以下的编程练习:int32 to IPv4。题目描述如下:

给定一个IPv4地址:128.32.10.1

这个地址由4个八位组成,每个八位都是一个字节(或8位)。

第一个八位 128 的二进制表示为:10000000
第二个八位 32 的二进制表示为:00100000
第三个八位 10 的二进制表示为:00001010
第四个八位 1 的二进制表示为: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 转换为字符串时,二进制表示没有补足零:

ip: 0
binary: 0

我应该如何将 long 类型的 ip 值转换为始终具有32位(添加前导零)的二进制字符串?

我尝试了以下的方法:

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)

我已经阅读过:

英文:

I am doing the following programming exercise: int32 to IPv4. The statement is:

> Take the following IPv4 address: 128.32.10.1
>
> This address has 4 octets where each octet is a single byte (or 8
> bits).
>
> 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
>
> So 128.32.10.1 == 10000000.00100000.00001010.00000001
>
> Because the above IP address has 32 bits, we can represent it as the
> unsigned 32 bit number: 2149583361
>
> Complete the function that takes an unsigned 32 bit number and returns
> a string representation of its IPv4 address. Examples
>
> 2149583361 ==> "128.32.10.1" 32 ==> "0.0.0.32" 0 ==>
> "0.0.0.0"

First, I tried the following code:

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));
	}
}

And being the tests:

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));
	}
}

When input is zero, my code throws an exception: java.lang.StringIndexOutOfBoundsException: begin 0, end 8, length 1
at Kata.longToIP(Kata.java:6)

Because of at line 4, where I convert from long to string, binary has not padding zeros:

ip: 0
binary: 0

How could I cast the long ip value to a binary string with always 32 digits (adding padding 0)?

I tried the following approach:

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));
	}
}

And it throws java.lang.NumberFormatException: For input string: "10000000011100100001000101101000" at Kata.longToIP(Kata.java:4)

Then I changed it to:

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));
	}
}

And this also throws an exception:

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

I have read:

答案1

得分: 2

public class Kata {
    public static String longToIP(long ip) {
        //1. 将ip转换为二进制表示
        String str = "";
        if (ip == 0) {
            str = ip + "";
        } else {
            while (ip != 0) {
                str = ip % 2 + str;
                ip = ip / 2;
            }
        }

        //2. 如果二进制字符串长度小于32位,则在前面添加"0"
        while (str.length() != 32) {
            str = "0" + str;
        }

        String result = "";

        //3. 将str分割为四个部分
        for (int i = 0; i < 4; i++) {
            String partStr = str.substring(i * 8, 8 * (i + 1));

            //4. 将每个部分转换为十进制数
            int bi = Integer.parseInt(partStr, 2);
            if (i == 3) {
                result += bi + "";
            } else {
                result += bi + ".";
            }
        }
        return result;
    }
}
英文:
public class Kata {
    public static String longToIP(long ip) {
        //1. translate the ip to binary representation
        String str = &quot;&quot;;
        if (ip == 0) {
            str = ip + &quot;&quot;;
        } else {
            while (ip != 0) {
                str = ip % 2 + str;
                ip = ip / 2;
            }
        }

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

        String result = &quot;&quot;;

        //3. truncate the str to four items
        for (int i = 0; i &lt; 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 + &quot;&quot;;
            } else {
                result += bi + &quot;.&quot;;
            }
        }
        return result;
    }
}

答案2

得分: 0

以下是翻译好的内容:

我们可以添加填充零:

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 对这个主题的回答 https://stackoverflow.com/questions/24456718/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;
        }
    }
}
英文:

We could add padding zeros:

public class Kata {
	public static String longToIP(long ip) {
		System.out.println(&quot;ip: &quot;+ip);
    String binary = Long.toBinaryString(ip);
    if(binary.length()&lt;32) binary = &quot;0&quot;.repeat(32-binary.length()) + binary;
    System.out.println(&quot;binary: &quot;+binary);
    return String.format(&quot;%s.%s.%s.%s&quot;,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));
	}
}

Or, we could do it in the same sentence where we convert from long to binary string, using format (based on Jeff Scott Brown answer to this topic https://stackoverflow.com/questions/24456718/converting-long-to-binary-in-java-gives-31-bits:

public class Kata {
	public static String longToIP(long ip) {
		System.out.println(&quot;ip: &quot;+ip);
    String binary = String.format(&quot;%32s&quot;,Long.toBinaryString(ip)).replace(&#39; &#39;,&#39;0&#39;); 
    System.out.println(&quot;binary: &quot;+binary);
    return String.format(&quot;%s.%s.%s.%s&quot;,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));
	}
}

In addition we could use net java libraries (Angelwrith solution):

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

得分: 0

// 将整数值转换为标准点分十进制格式,以下代码可以实现。只需将值从左侧按递减的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;
}

// 将整数转换为长度为32的填充二进制值,可以尝试以下代码。它确保将传递的整数转换为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
英文:

To convert an int value to the standard dotted quad format, this will work. It is a simple matter of shifting the values from the left by decreasing values of 8 and appending the appropriate strings.

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

To convert an int to a padded binary value of length 32, try the following. It ensures that the passed int is converted to a 33 bit value so the standard Long.toBinaryString method will return a 33 character value. The first character is tossed since it has served its purpose.

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

The following code shows the output.

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

Prints

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
</details>

huangapple
  • 本文由 发表于 2020年3月15日 21:44:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/60693546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定