Преобразовать целое число в байтовый массив (Java)

137

Какой быстрый способ преобразовать Integerв Byte Array?

например 0xAABBCCDD => {AA, BB, CC, DD}

Лютик
источник
1
Имеет ли значение какой формат результирующего байтового массива? Что ты будешь делать с этим?
Скаффман

Ответы:

237

Посмотрите на класс ByteBuffer .

ByteBuffer b = ByteBuffer.allocate(4);
//b.order(ByteOrder.BIG_ENDIAN); // optional, the initial order of a byte buffer is always BIG_ENDIAN.
b.putInt(0xAABBCCDD);

byte[] result = b.array();

Установка обеспечивает порядка байтов , что result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCCи result[3] == 0xDD.

Или же вы можете сделать это вручную:

byte[] toBytes(int i)
{
  byte[] result = new byte[4];

  result[0] = (byte) (i >> 24);
  result[1] = (byte) (i >> 16);
  result[2] = (byte) (i >> 8);
  result[3] = (byte) (i /*>> 0*/);

  return result;
}

ByteBufferКласс был разработан для таких грязных рук задач , хотя. Фактически, private java.nio.Bitsопределяет эти вспомогательные методы, которые используются ByteBuffer.putInt():

private static byte int3(int x) { return (byte)(x >> 24); }
private static byte int2(int x) { return (byte)(x >> 16); }
private static byte int1(int x) { return (byte)(x >>  8); }
private static byte int0(int x) { return (byte)(x >>  0); }
Григорий Пакош
источник
3
это бы хорошо работало, если бы байтовый буфер уже был там ... в противном случае кажется, что это заняло бы больше времени, чем просто выделение байтового массива длины 4 и выполнение сдвига вручную ... но мы, вероятно, говорим о небольших различиях.
Джейсон С
Экземпляр ByteBuffer может быть кэширован; и внутренне это конечно выполнено с перемещением и маскировкой так или иначе.
Григорий Пакош,
4
Это прекрасный ответ. Обратите внимание, что big-endian является указанным по умолчанию, а методы являются «цепочечными», а аргумент position является необязательным, поэтому все сводится к: byte [] result = ByteBuffer.allocate (4) .putInt (0xAABBCCDD) .array ( ); Конечно, если вы делаете это многократно и объединяете все результаты вместе (что часто случается, когда вы делаете подобные вещи), выделите один буфер и многократно вставьте в него все, что вам нужно - он будет следить за смещением по мере движения. Это действительно чрезвычайно полезный класс.
Кевин Бурриллион
что это дает для подписанных типов?
Григорий Пакош
3
Для тех, кто не знает. PutInt всегда записывает 4 байта, независимо от размера входного целого числа. Если вам нужны только 2 байта, используйте putShort и т. Д.
bvdb
36

Использование BigInteger:

private byte[] bigIntToByteArray( final int i ) {
    BigInteger bigInt = BigInteger.valueOf(i);      
    return bigInt.toByteArray();
}

Использование DataOutputStream:

private byte[] intToByteArray ( final int i ) throws IOException {      
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);
    dos.writeInt(i);
    dos.flush();
    return bos.toByteArray();
}

Использование ByteBuffer:

public byte[] intToBytes( final int i ) {
    ByteBuffer bb = ByteBuffer.allocate(4); 
    bb.putInt(i); 
    return bb.array();
}
Паскаль Тивент
источник
5
обратите внимание на порядок байтов, хотя
Грегори Pakosz
1
ByteBuffer выдает неподписанный int?
Арун Джордж
@Pascal Использование ByteBuffer Я пытался с ByteBuffer bb = ByteBuffer.allocate (3); Для этого он дает java.nio.BufferOverflowException, я не понимаю, почему он не работает для значения меньше 4? Не могли бы вы объяснить?
Санджай Джейн,
@SanjayJain Вы получаете исключение переполнения буфера, потому что в Java целые 32-битные или 4-байтовые по размеру, и, следовательно, вы должны выделить как минимум 4 байта памяти в вашем ByteBuffer.
шокирующая
@GregoryPakosz прав насчет порядка байтов. Его использование ответа ByteBufferболее интуитивно
понятно,
31

используйте эту функцию, она работает для меня

public byte[] toByteArray(int value) {
    return new byte[] {
            (byte)(value >> 24),
            (byte)(value >> 16),
            (byte)(value >> 8),
            (byte)value};
}

он переводит int в байтовое значение

DAZ
источник
Также ничего не стоит, что это будет работать независимо от самого значительного и более эффективного по сравнению с другими ответами. Также можно использовать «>>».
Алкогольный
1
Такое прямое решение, безусловно, быстрее, чем вызов любого библиотечного метода. Иногда вам просто нужно поиграться с битами непосредственно с помощью нескольких строк кода, вместо того, чтобы брать на себя все лишние затраты на вызовы библиотечных методов.
Дэвид Р. Триббл
И это хорошо конвертирует между языками, что хорошо для многоязычной разработки программного обеспечения.
Координатор
15

Если вам нравится Guava , вы можете использовать его Intsкласс:


Для intbyte[]используйте toByteArray():

byte[] byteArray = Ints.toByteArray(0xAABBCCDD);

Результат есть {0xAA, 0xBB, 0xCC, 0xDD}.


Его реверс fromByteArray()или fromBytes():

int intValue = Ints.fromByteArray(new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD});
int intValue = Ints.fromBytes((byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD);

Результат есть 0xAABBCCDD.

острая боль
источник
8

Вы можете использовать BigInteger:

Из целых чисел:

byte[] array = BigInteger.valueOf(0xAABBCCDD).toByteArray();
System.out.println(Arrays.toString(array))
// --> {-86, -69, -52, -35 }

Возвращаемый массив имеет размер, необходимый для представления числа, поэтому он может иметь размер 1, например, 1. Однако размер не может быть больше четырех байтов, если передается int.

Из строк:

BigInteger v = new BigInteger("AABBCCDD", 16);
byte[] array = v.toByteArray();

Тем не менее, вам нужно следить, если первый байт будет выше 0x7F(как в этом случае), где BigInteger вставит байт 0x00 в начало массива. Это необходимо для различения положительных и отрицательных значений.

notnoop
источник
Спасибо! Но так как это BigInteger, правильно ли обернуты int? То есть целые числа, которые находятся вне Integer.MAX_VALUE, но все еще могут быть представлены только 4 байтами?
Лютик
1
Это, конечно, не быстро выполнить. ;)
Питер Лори
Это не хороший вариант. Мало того, что он может добавить 0x00 байт, он также может удалить начальные нули.
ZZ Coder
1

Простое решение, которое правильно обрабатывает ByteOrder:

ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(yourInt).array();

Хелми
источник
1

очень легко с Android

int i=10000;
byte b1=(byte)Color.alpha(i);
byte b2=(byte)Color.red(i);
byte b3=(byte)Color.green(i);
byte b4=(byte)Color.blue(i);
Мукеш Бамбхания
источник
1

Это поможет вам.

import java.nio.ByteBuffer;
import java.util.Arrays;

public class MyClass
{
    public static void main(String args[]) {
        byte [] hbhbytes = ByteBuffer.allocate(4).putInt(16666666).array();

        System.out.println(Arrays.toString(hbhbytes));
    }
}
вай
источник
0

Можно также сдвинуть -

byte[] ba = new byte[4];
int val = Integer.MAX_VALUE;

for(byte i=0;i<4;i++)
    ba[i] = (byte)(val >> i*8);
    //ba[3-i] = (byte)(val >> i*8); //Big-endian
Matt
источник
0

Вот метод, который должен делать работу правильно.

public byte[] toByteArray(int value)
{
    final byte[] destination = new byte[Integer.BYTES];
    for(int index = Integer.BYTES - 1; index >= 0; index--)
    {
        destination[i] = (byte) value;
        value = value >> 8;
    };
    return destination;
};
user3424779
источник
0

Это мое решение:

public void getBytes(int val) {
    byte[] bytes = new byte[Integer.BYTES];
    for (int i = 0;i < bytes.length; i ++) {
        int j = val % Byte.MAX_VALUE;
        bytes[i] = (j == 0 ? Byte.MAX_VALUE : j);
    }
}

Также Stringу метод:

public void getBytes(int val) {
    String hex = Integer.toHexString(val);
    byte[] val = new byte[hex.length()/2]; // because byte is 2 hex chars
    for (int i = 0; i < hex.length(); i+=2)
        val[i] = Byte.parseByte("0x" + hex.substring(i, i+2), 16);
    return val;
}
Muskovets
источник