Перетворення коротких бітів на int

У мене є пакет TCP, який надсилає купу змінних без знаку (вони без знаку, тому що вони економлять місце та використовують обмеження для унікальних ідентифікаторів), мені потрібно перетворити ці короткі бітові дані без знаку в ціле число в java.

Отже, моє запитання полягає в тому, як мені перетворити byteArray[0 - 15] на int?

Редагувати:

Ось код, на який я змінив:

ByteOrder order = ByteOrder.BIG_ENDIAN;
requestedDateType = new BigInteger(ByteBuffer.allocate(2).put(data, 8, 2).order(order).array()).intValue();

Надходить буфер даних:

bit   0    1   2   3   4   5   6   7   8   9

value 40   0   0   0   8   0   0   0   1   0

Дані надсилаються як Little Endian. Я припускаю, що оскільки BigInteger передбачає великий, мені потрібно перетворити на це. Однак і велике, і маленьке замовлення дають мені однакову цінність.

Я очікую отримати 1 для значення requestedDateType, однак отримую 256. Як доповнити два відсутні байти, щоб переконатися, що це дає мені 0000 0000 0000 0001 замість 0000 0001 0000 0000

Редагувати 2:

Не зважай. Змінено код на такий:

ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(data, 8, 2);
int value = ((int)bb.getShort(0)) & 0xff;

person JeremyK    schedule 24.06.2013    source джерело


Відповіді (2)


Використовуйте ByteBuffer у пакеті java.nio.

//Convert unsigned short to bytes:
//java has no unsigned short. Char is the equivalent.
char unsignedShort = 100;
//Endianess of bytes. I recommend setting explicitly for clarity
ByteOrder order = ByteOrder.BIG_ENDIAN;
byte[] ary = ByteBuffer.allocate(2).putChar(value).order(order).array();

//get integers from 16 bytes
byte[] bytes = new byte[16];
ByteBuffer buffer= ByteBuffer.wrap(bytes);
for(int i=0;i<4;i++){
    int intValue = (int)buffer.getInt();
}

Guava також має процедури для примітивного перетворення на байт, якщо вас цікавить зовнішня бібліотека: http://code.google.com/p/guava-libraries/

Крім того, я не знаю ваш прецедент використання, але якщо ви перебуваєте на початковій стадії свого проекту, я б використав Google ProtoBufs для обміну інформацією про протокол. Це полегшує головний біль під час переходу між версіями протоколу, створює дуже компактний двійковий вихід і є швидким.

Крім того, якщо ви коли-небудь зміните мову, ви можете знайти бібліотеку protobufs для цієї мови і не переписувати весь код свого протоколу.

http://code.google.com/p/protobuf/

person William Morrison    schedule 24.06.2013
comment
Чи зробив би ByteBuffer.wrap(bytes).getInt() те саме? - person Petr Janeček; 25.06.2013
comment
Так, сер, я додам для цього приклад. - person William Morrison; 25.06.2013

Зрештою я скористався цим ресурсом: http://www.javamex.com/java_equivalents/unsigned.shtml

ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(data, 8, 2);
requestedDateType = ((int)bb.getShort(0)) & 0xff;

Я скопіював два байти в short, потім перетворив його на int і видалив знак.

person JeremyK    schedule 25.06.2013