Как преобразовать байтовый массив в его числовое значение (Java)?
У меня есть 8-байтовый массив, и я хочу преобразовать его в соответствующее числовое значение.
например
byte[] by = new byte[8]; // the byte array is stored in 'by'
// CONVERSION OPERATION
// return the numeric value
Я хочу метод, который будет выполнять вышеуказанную операцию преобразования.
9 ответов
Предполагая, что первый байт является наименее значимым байтом:
long value = 0;
for (int i = 0; i < by.length; i++)
{
value += ((long) by[i] & 0xffL) << (8 * i);
}
Является ли первый байт самым значимым, тогда он немного отличается:
long value = 0;
for (int i = 0; i < by.length; i++)
{
value = (value << 8) + (by[i] & 0xff);
}
Замените long на BigInteger, если у вас больше 8 байтов.
Спасибо Аарону Дигулле за исправление моих ошибок.
Можно использовать Buffer
ы, которые предоставляются как часть java.nio
пакет для выполнения конвертации.
Здесь источник byte[]
массив имеет длину 8, что соответствует размеру long
значение.
Во-первых, byte[]
массив обернут в ByteBuffer
а затем ByteBuffer.getLong
метод вызывается для получения long
значение:
ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();
System.out.println(l);
Результат
4
Я хотел бы поблагодарить dfa за указание на ByteBuffer.getLong
Метод в комментариях.
Хотя это не может быть применимо в этой ситуации, красота Buffer
приходят с просмотром массива с несколькими значениями.
Например, если у нас есть 8-байтовый массив, и мы хотим рассмотреть его как два int
ценности, мы могли бы обернуть byte[]
массив в ByteBuffer
, который рассматривается как IntBuffer
и получить значения по IntBuffer.get
:
ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);
System.out.println(i0);
System.out.println(i1);
Результат:
1
4
Если это 8-байтовое числовое значение, вы можете попробовать:
BigInteger n = new BigInteger(byteArray);
Если это символьный буфер UTF-8, то вы можете попробовать:
BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));
Проще говоря, вы можете использовать или ссылаться на библиотеку guava, предоставляемую Google, которая предлагает методы для преобразования между длинным и байтовым массивом. Мой код клиента:
long content = 212000607777l;
byte[] numberByte = Longs.toByteArray(content);
logger.info(Longs.fromByteArray(numberByte));
Вы также можете использовать BigInteger для байтов переменной длины. Вы можете преобразовать его в Long, Integer или Short, в зависимости от ваших потребностей.
new BigInteger(bytes).intValue();
или для обозначения полярности:
new BigInteger(1, bytes).intValue();
Полный код Java-конвертера для всех типов примитивов в / из массивов http://www.daniweb.com/code/snippet216874.html
Каждая ячейка в массиве обрабатывается как unsigned int:
private int unsignedIntFromByteArray(byte[] bytes) {
int res = 0;
if (bytes == null)
return res;
for (int i=0;i<bytes.length;i++){
res = res | ((bytes[i] & 0xff) << i*8);
}
return res;
}
public static long byteArrayToLong(byte[] bytes) {
return ((long) (bytes[0]) << 56)
+ (((long) bytes[1] & 0xFF) << 48)
+ ((long) (bytes[2] & 0xFF) << 40)
+ ((long) (bytes[3] & 0xFF) << 32)
+ ((long) (bytes[4] & 0xFF) << 24)
+ ((bytes[5] & 0xFF) << 16)
+ ((bytes[6] & 0xFF) << 8)
+ (bytes[7] & 0xFF);
}
преобразовать массив байтов (длинный 8 байт) в длинный
Вы можете попробовать использовать код из этого ответа: /questions/13570107/kak-mne-preobrazovat-bajt-v-dlinnyij-v-java/59368338#59368338
Он анализирует байты как число со знаком произвольной длины. Несколько примеров:
bytesToSignedNumber(false, 0xF1, 0x01, 0x04)
возвращается
15794436
(3 байта как int )
bytesToSignedNumber(false, 0xF1, 0x01, 0x01, 0x04)
возвращается
-251592444
(4 байта как int )
bytesToSignedNumber(false, 0xF1, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04)
возвращается
-1080581331768770303
(8 из 9 байтов длиной )