Java出力InetAddressで取得したIPアドレス配列の詳細解析

1458 ワード

InetAddressを使用してIPアドレスを取得するとbyte配列が得られます.この配列を直接出力すると、IPアドレスの一部のビットが61.135のように負の数になっていることがわかります.169.105は61に出力されます.121.-87.105よく見ると135+121=256169+87=256--!どういうことだ!まずbyteタイプからintタイプへの変換中に問題が発生したことを考えましたが、実際にはそうではありません.
Javaにはunsignedタイプがないためbyte,short,int,longともにシンボルがあるため,暗黙タイプ変換エラーの問題はまったく存在しない.
Javaにunsignedタイプがないといえばbyteは8ビットなので、表示範囲は-127-128、IP 1セグメントの表示範囲は0-255と、やっと変なところを見つけました
IPのセグメントはunsigned byteであり、このようなunsigned byteがsigned byteに格納されると、当然いくつかの問題が発生する.
分析してみます:35のバイナリコードは1000 0111で、最高の位置は1です
byteはunsigned byteとされているため、最上位の1はシンボルビットと解釈され、またJavaに格納されているのは符号化に従って格納されているため、1000,0111は符号化形式とみなされ、元の符号に変換すると1111,000 1,000 1、10進数に変換すると-121となる.
なお、65のバイナリ符号化は0100 0001であり、128未満であるため、最高位置10100 0001の符号化は0100 0001ではないので、65は変わらない.
このように分析すると、この問題の解決方法は簡単で、byte変数と0 xFFをビットとすればよい.過程でbyteは暗黙的なタイプをintに変換し、0 xFFとビットを合わせると、8ビット低い他のビットをすべて0にし、シンボルが拡張された高位をクリアする.
最後に、整数変数のバイナリ符号化出力に使用する独自の汎用関数を添付します.
 
  
/**
 *
 * @param n
 * @param size , Short.SIZE
 * @return
 */
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();
}