Javaでバイナリデータ(byte配列)から整数に変換する

追加ライブラリなどを使わずに、Javaでbyte配列から整数に変換する方法です。
バイナリデータを解析する際、ヘッダ部分にデータサイズが入っているなんて場合に使えます。

計算で変換する

shortなど符号付の変換をしたい場合。

  1. 各byte値を上位の型(下記サンプルではshort)にキャスト
  2. 符号部分をマスクする
  3. ビットシフト相当の値を掛ける
  4. すべての値を加算
// 2,147,483,647
byte[] bytes = new byte[]{(byte) 0x7F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
int value = (((short) bytes[0]) & 0x00FF) * 16777216 +
        (((short) bytes[1]) & 0x00FF) * 65536 +
        (((short) bytes[2]) & 0x00FF) * 256 +
        (((short) bytes[3]) & 0x00FF);
Log.i("BYTE TO INT", "" + value);

ログの出力

BYTE TO INT: 2147483647

short型の場合

short high = (short)(((short)bytes[0] & 0x00FF) * 256);
short low = (short)((short)bytes[1] & 0x00FF);
int value = high + low;

文字列と数値の変換を使う

符号なし(unsigned shortなど)の場合。16進表記の文字列に変換→16進数の文字列を整数にする方法です。
文字列の16進表記は正の値とみなされます。つまりunsignedになります。

// ‭16,777,125‬
byte[] bytes = new byte[]{0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xA5};
String tmp = String.format("%02X%02X%02X%02X", bytes[0], bytes[1], bytes[2], bytes[3]);
Log.i("BYTE TO INT", "0x" + tmp);
int value = Integer.parseInt(tmp, 16);
Log.i("BYTE TO INT", "" + value);

ログの出力

BYTE TO INT: 0x00FFFFA5
BYTE TO INT: 16777125
unsigned intには対応できません。

符号なし変換について

Java 8からは符号なし変換(Byte.toUnsignedInt()など)でキャストも不要です。unsigned intも扱えます。 しかし、Android StudioではAPI level 26以上しか使えません。 アプリ開発で使うにはまだまだ早いかな、と。

このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です