The Java output is parsed through the array of IP addresses obtained by InetAddress

  • 2020-04-01 02:20:50
  • OfStack

Using InetAddress to get the IP address gives you a byte array
If you output the array directly, you will find that some bits in the IP address become negative
For example, 61.135.169.105 will be output as 61.-121.-87.105
A closer look reveals that 135 + 121 = 256, 169 + 87 = 256

-_ -! What a situation!

My first thought was that there had been a problem converting from byte to int

Since there are no unsigned types in Java, byte, short, int, and long are signed, so there is no problem with implicit type conversions.

Now that Java has no unsigned type, byte is 8 bits, so the range is -127-128, and IP is a segment of the range is 0-255, so something is wrong

An IP segment is an unsigned byte, and this unsigned byte is stored in a signed byte, which of course causes some problems

Analyze it:
The binary code of 35 is 1000 0111 and the highest position is 1

Since byte is considered unsigned byte, the highest bit of 1 will be interpreted as a sign bit, and the storage in Java is stored as a complement, so 1000 0111 will be considered as a complement, converted to source code is 1111 0001, converted to decimal number is -121.

Now, the binary code of 65 is 01000001. Since it is less than 128, the complement of 101000001 at the highest position is not changed to 01000001, so 65 remains unchanged.

With all this analysis, the solution to this problem is simple: byte variables are bitwise summed with 0xFF. Byte is implicitly typed to int, and when byte is bitwise summed with 0xFF, all bits except the lower 8 bits are set to 0, thus eliminating the high points of symbol extension.

Finally, I attach a generic function written by myself, which is used to encode the binary output of integer variables



public static String printBinary(long n, int size) {
 StringBuilder sb = new StringBuilder();
 for (int i = size - 1; i >= 0; i--) {
  sb.append(n >>> i & 0x01);
  if (i % 4 == 0) {
   sb.append(" ");
  }
 }
 return sb.toString();
}


Related articles: