2013-09-25 30 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