Pregunta

Estoy tratando de voltear algunos bytes en Java y la función que tengo está funcionando correctamente para algunos bytes y fallar para otros.

La función que estoy usando es esta:

public static int foldInByte(int m, int pos, byte b) {
    int tempInt = (b << (pos * 8));
    tempInt = tempInt & (0x000000ff << (pos * 8));
    m = m | tempInt;
    return m;
}

Y el código que implementa esto es:

byte[] bitMaskArray = new byte[]{
                            byteBuffer.get(inputIndex),
                            byteBuffer.get(inputIndex + 1),
                            byteBuffer.get(inputIndex + 2),
                            byteBuffer.get(inputIndex + 3)};
                        int tempInt = 0;

                        tempInt = foldInByte(0, 3, bitMaskArray[3]);
                        tempInt = foldInByte(tempInt, 2, bitMaskArray[2]);
                        tempInt = foldInByte(tempInt, 1, bitMaskArray[1]);
                        tempInt = foldInByte(tempInt, 0, bitMaskArray[0]);

                        bitMask = tempInt;

Los bytes se leen de un bytebuffer con el byteorder siendo Little Endian.

Por ejemplo, los bytes 00 01 B6 02 establecen la masa de bits en: 2B60100, que funciona perfectamente en mi programa.

Sin embargo, si los bytes son A0 01 30 00, la máscara de bits se establece en: 3001A0, que ha sacado el último cero de la maestría de bits.

¿Hay alguna forma de evitar que Java quite los ceros de arrastre?

Espero que tenga sentido.

Gracias

Tony

¿Fue útil?

Solución

Los ceros no están siendo despojados; ambos ejemplos citados son correctos.

  • 00 01 B6 02 es el Little-endian de 4 bytes para 2B60100
  • A0 01 30 00 es el Little-endian de 4 bytes para 3001A0

Los ceros están allí, pero probablemente no se impriman. La familia de llamadas System.out.print no imprimirá cero dígitos líderes.

Podría mencionar que su método es innecesariamente complejo. Aquí hay un solo método que calcula el mismo valor:

static int extractLittleEndian4(byte[] buf, int index)
{
    int a = buf[index+0]&0xff, b = buf[index+1]&0xff, c = buf[index+2]&0xff, d = buf[index+3]&0xff;
    return a | (b << 8) | (c << 16) | (d << 24);
}

Otros consejos

Parece que ya tienes un bytebuffer lleno de tus bytes. ¿Por qué no dejas que el bytebuffer revertira los bytes para ti? Simplemente agregue los bytes al búfer (Big_endian es el valor predeterminado si desea agregar un entero en lugar de bytes) y luego cambie el pedido antes de leer el entero.

byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
int output = byteBuffer.getInt(0);

Si todo lo que está haciendo es revertir el pedido de bytes, deje que la biblioteca haga el trabajo por usted. Si comenzó con un valor entero, incluso puede hacer esto:

int input = ...;
int output = Integer.reverseBytes(input);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top