2013-09-25 25 views
0

我有一个简单的程序来查找我的IP地址并将其转换为字符串。 为什么b[i]值低于(int)255为什么ip地址值是和int 255

public class FirstSocketProgramming { 

public static void main (String arg[]){ 

    InetAddress local = null; 

    try { 

    local = InetAddress.getLocalHost(); 

    } catch (UnknownHostException e){ 

    System.err.println 

     ("Identity Crisis!"); 

    System.exit(0); 

    } 

byte[] b = local.getAddress(); 

System.out.println (b.toString()); 
System.out.println (b.length); 
String strAddress=""; 

for (int i = 0; i < b.length; i++) 

    strAddress += ((int)255&b[i]) + "."; 

System.out.println ("Local = " + strAddress); 

} 

} 

回答

3

byte数据类型基于Two's complement二进制带符号的数字表示形式,值的范围从-128到+127。

正值从0到127有最高有效位等于0代表+。 这里二进制表示是相同的,因为它从-128的数值,例如byte 00000100 = int 4

负值为-1有它的最显著位等于代表- 然而,在负的范围内1,二进制补码表示是NOT与其数值相同,例如,您会预计byte 10000100等于int 132,但实际上是-124。 简单地将byte投射到int将无济于事。

铸造只是扩大1字节到4 btytes,10000100 ==> 11111111111111111111111110000100这等于-124,而不是132,因为int数据类型也是基于二进制补码。将byte铸造成int是朝着正确方向迈出的一步,但是您也需要摆脱前面的所有这些。 255&b[i]诀窍实现了这一点。

这是255&b[i]会发生什么:
根据在该JLS&位运算符首先将它的操作数为int,这意味着255&b[i]相同((int)255)&((int)b[i])定义的转换规则。当字节被强制转换为int它只是变得更宽:

10000100 = byte -124 ==> 11111111111111111111111110000100 = int -124

然后按位与执行。

11111111111111111111111110000100 = int -124 
& 
00000000000000000000000011111111 = int 255 
-------------------------------- 
00000000000000000000000010000100 = int 132 

最终结果是int 132

3

它的符号字节转换为整数,让你得到全方位的(无符号)8位,而不是显示在127

在Java中的值是负数,因为字节是有符号的,一个字节的最大值是127.所以可以说这个数字是128.在一个无符号字节中,这将表示为10000000b。然而,用2的补码负数,这变成了-128。做255 & b [i]将值强制为一个整数(32位)并将高位清零,以便得到128而不是-128。

+0

很好的答案,但我得批评你的措辞一点。 “全范围的8位”仍然遵循-128至127的规定,除非由于位作为符号位而移位。不过,这个想法是正确的。 – hexafraction

+0

请解释-1? –

+0

不是我,我认为这也是有效的。 – hexafraction

3

的地址被写为一组字节,从0到255的Java解释每个字节作为从-128签署一个〜127因此,形成从字节的字符串作为签署者将是无意义的,例如-18.14.87.-45。这与IP表示不符。

(int)255&b[i] 

蒙上b[i]int而加宽了,从而忽略标志和读取它作为无符号的。 (int)是轻微的,因为255已被解释为比8位宽的东西。 0-255值连接在一起。因此,您获得了一个类似192.168.1.200的IP(请注意,此地址与之前给出的错误地址不符)。

作为一般的事情做255&foo(或任何2^n-1为整数n,如65536,甚至像十二进制0xFF十六进制)是一个尝试安全地投入位长度。

+0

即使删除了“(int)”加宽,意味着(255&b [i])本身就足够了,所以扩展在这里看起来不是必要的。 – dganesh2002

+0

@ dganesh2002然而,它在那里,所以我正在回答它的上下文。 “(int)'是轻浮的,因为'255'已经被解释为比8位宽的东西。” – hexafraction

+0

downvoter请解释推理? (@ dganesh2002它被修复了) – hexafraction

0

该ip地址是逻辑和subnet_mask找到net_id和host_id。在这个例子中,它是相同的,但非常不寻常。 subnet_mask可以用来分割出许多net_id。请阅读此处的示例:http://www.garykessler.net/library/subnet_masks.html

+0

这与Java Cast的细节有什么关系?这只是地址和掩码可以做的一个总结。 – hexafraction

+0

子网掩码也是255.你怎么知道这是一个演员的东西? – Bytemain

+0

在代码的上下文中阅读它的用法。它在这里以另一种方式使用,而不是你所描述的。由于其掩码属性,子网掩码只有255个,因此它适用于全部字节。尽管失败也不是一个真正合理的举动。如果你注意到的话,我一点也不会让你失望。 – hexafraction