Java - присвоить значение массиву фиксированных байтов - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь присвоить целочисленное значение аномальному массиву байтов фиксированного размера (3).Я видел функцию выделения байтовых буферов, однако putInt пытается вставить 4 байта, которые затем ломаются из-за переполнения

Например:

byte[] messageLength = ByteBuffer.allocate(3).putInt(Integer.parseUnsignedInt("300")).array();

Результатом является следующее исключение

Exception in thread "main" java.nio.BufferOverflowException
at java.nio.Buffer.nextPutIndex(Buffer.java:527)
at java.nio.HeapByteBuffer.putInt(HeapByteBuffer.java:372)

Очевидно, что 300 может вписаться в 3 байта, поскольку в двоичном виде это 0001 0010 1100.

Что я могу сделать, чтобы поместить целочисленное значение совершенно правильного размера в массив из 4 байтов?

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Простым решением является преобразование значения Integer в byte[], который содержит только необходимые биты.Следующий код работает с целыми числами, которые помещаются в 1, 2, 3 и 4 байта:

private static byte[] compressInteger(int value) {
    if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
        return new byte[] { (byte) value };
    } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
        return new byte[] { (byte) (value >>> 8), (byte) (value) };
    } else if ((byte)(value >>> 24) == 0) {
        return new byte[] { (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value) };
    } else {
        return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) (value) };
    }
}

Если вы хотите преобразовать byte[] обратно в целочисленное значение, вы можете сделать:

private static int decompressInteger(byte[] bytes) {
    int value = 0;
    for (int i = bytes.length - 1; i >= 0; i--) {
        for (int bit = 0; bit <= 7; bit++) {
            boolean isSet = ((bytes[i] >>> bit) & 1) == 1;
            if (isSet) {
                int shift = 8 * (bytes.length - 1 - i) + bit;
                int mask = 1 << shift;
                value |= mask;
            }
        }
    }
    return value;
}
0 голосов
/ 26 октября 2018

Вам нужно 4 байта, чтобы выделить Integer внутри байтового буфера.Вы можете читать из байтового буфера вручную, если вам нужно специальное правило распаковки.

Вот пример:

public static byte[] convertInts(int[] source) {
    ByteBuffer buffer = ByteBuffer.allocate(4 * source.length);
    for (int data : source) {
        buffer.putInt(data);
    }
    buffer.flip();

    byte[] destination = new byte[3 * source.length];
    for (int i = 0; i < source.length; i++) {
        buffer.get();
        destination[i * 3] = buffer.get();
        destination[i * 3 + 1] = buffer.get();
        destination[i * 3 + 2] = buffer.get();
    }

    return destination;
}

Пример использования:

int[] source = {
    Integer.parseUnsignedInt("30"),
    Integer.parseUnsignedInt("300"),
    Integer.parseUnsignedInt("3000"),
    Integer.parseUnsignedInt("300000"),
};
byte[] data = convertInts(source);
...