2017-01-31 3 views
0

Как преобразовать массив байтовых блоков от 4 до целого числа.преобразовать массив байтовых блоков в DWORD (int) Java

Если бы мы имели эти байты файла в Hex Editor:

CB 01 00 00 

Значение шестнадцатеричного этого блока DWORD из 000001CB = 1CB гекса = 459 в десятичной системе счисления.

Как преобразовать любой массив байтов (byte[]) блок (из четырех байтов) в целое (десятичное значение блока)?

Ищу метода, как это:

public int getDecimalFromBlock(byte... bytes) { 
     for (byte b: bytes) { 
      // do the magic 
     } 
} 

где параметр байт число между диапазоном байтов (-127, 127).

+0

Прочитайте его в ByteBuffer, установите для параметра Byte Buffer значение LITTLE_ENDIAN и вызовите метод getInt ByteBuffer. – VGR

ответ

2

Давайте предположим, что ваш заказ байт Little Endian (на основании вашего поста), и поэтому декодирование будет

int value = ((data[0]&0xff) | 
    ((data[1]&0xff)<<8) | 
    ((data[2]&0xff)<<16) | 
    ((data[3]&0xff)<<24)); 

Если заказ большой обратный порядок байт, это будет выглядеть примерно так:

int value = ((data[3]&0xff) | 
    ((data[2]&0xff)<<8) | 
    ((data[1]&0xff)<<16) | 
    ((data[0]&0xff)<<24)); 

В обоих случаях вариант "данных" является "байт []"

byte[] data = new byte[] {(byte)0xcb, 0x01, 0x00, 0x00}; 

Обн съели отредактированный запрос.

Я предполагаю, что вы можете иметь проблемы с 0xcb, как интерпретируется как отрицательное значение, то это может быть исправлено путем применения & оператора

Полный код с теста

public class DecimalTest 
{ 
    public static int getDecimalFromBlock(byte... bytes) { 
     int result = 0; 
     for(int i=0; i<bytes.length; i++) 
     { 
      result = result | (bytes[i] & 0xff)<<(i*8); 
     } 
     return result; 
    } 

    public static void main(String[] args) throws IOException 
    { 
     System.out.println(getDecimalFromBlock(new byte[]{(byte)0xcb})); 
     System.out.println(getDecimalFromBlock(new byte[]{(byte)0xcb, 0x01})); 
     System.out.println(getDecimalFromBlock(new byte[]{(byte)0xcb, 0x01, 0x00})); 
     System.out.println(getDecimalFromBlock(new byte[]{(byte)0xcb, 0x01, 0x00, 0x00})); 
     System.out.println(getDecimalFromBlock(new byte[]{(byte)0xcb, 0x01, 0x00, 0x00, 0x00})); 
    } 
} 
+0

Как установить метод? Обновлен мой вопрос. – user3734782

+0

Большое спасибо, решена моя проблема. Хорошего дня. – user3734782

+0

EDIT: У вас есть идея, как это сделать в обратном направлении? От целочисленного до байтового блока? У меня проблема с преобразованием hex «FE» (dec 254) для соответствия диапазону байтов ... – user3734782

0

Вы могли бы также иметь вид в библиотеке IO Apache Commons и ее классе EndianUtils. Именно для этой цели.

Пожалуйста, обратите внимание, что четыре байта DWORD (без знака) может только правильно отобразить на Java (подпись) long, как Java (подпись) int не может вместить все возможные значения DWORD (слишком большие значения приведут к отрицательному int). Таким образом, EndianUtils.readSwappedUnsignedInteger() правильно возвращает long.