Java 通过InetAddress 获得的 IP 地址数组

楼主
Java 通过InetAddress 获得的 IP 地址数组
[P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]      [/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]   [/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]    使用 InetAddress 获取 IP 地址会得到一个 byte 数组[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  如果你直接输出这个数组,你会发现 IP 地址中的某些位变成了负数[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  比如 61.135.169.105 会输出成 61.-121.-87.105[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  仔细看一看,会发现 135 + 121 = 256,169 + 87 = 256[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  -_-! 怎么个情况![/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  我首先想到的是 byte 类型向 int 类型转换过程中出现了问题,后来发现,实际不然[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  因为Java 中没有 unsigned 类型,所以byte、short、int、long 都是有符号的,所以根本就不存在隐式类型转换出错的问题。[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  既然说到了Java 没有 unsigned 类型,那么 byte 是 8 位,所以表示范围为 -127 - 128,而 IP 一个段的表示范围为 0 - 255,终于找到了不对劲的地方了[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  IP 的一个段是一个 unsigned byte,这样一个 unsigned byte 存入一个 signed byte 中当然会导致一些问题出现[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  分析一下:[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  35 的二进制编码为 1000 0111,最高位置为 1[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  由于 byte 被认为是 unsigned byte,所以最高位的 1 将会被解释为符号位,另外 Java 中存储是按照补码存储,所以 1000 0111 会被认为是补码形式,转换成原码便是 1111 0001,转换成十进制数便是 -121。[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  再看,65 的二进制编码为 0100 0001,由于小于 128,所以没有将最高位置 1,0100 0001 的补码还是 0100 0001,所以 65 不变。[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  分析这么多,这个问题的解决方法其实很简单,将 byte 变量与 0xFF 按位与即可,过程中 byte 会隐式类型转换为 int,当与 0xFF 按位与的时候,会将除了低 8 位的其他位全部置 0,这样一来便将符号扩展的那些高位清除掉了。[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]
[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  最后附上一个自己写的通用函数,用来将整型变量的二进制编码输出[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  Java代码[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  /**[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  * 将整型变量的二进制编码形式输出[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  * @param n 整型变量[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  * @param size 整型的二进制长度,可使用类似 Short.SIZE 获得[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  * @return 二进制编码字符串[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  */[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  public static String printBinary(long n, int size) {[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  StringBuilder sb = new StringBuilder();[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  for (int i = size - 1; i >= 0; i--) {[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  sb.append(n >>> i & 0x01);[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  if (i % 4 == 0) {[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  sb.append(" ");[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  }[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  }[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  return sb.toString();[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P][P][LINE-HEIGHT=21px][FACE=Simsun][COLOR=rgb(102, 102, 102)][BGCOLOR=rgb(255, 255, 255)][SIZE=14px]  }[/SIZE][/BGCOLOR][/COLOR][/FACE][/LINE-HEIGHT][/P]

电脑版 Page created in 0.0156 seconds with 3 queries.