Home   Contact   2017

<< Back

Integer to Byte Array in Java (Spanish)

Código:

// Integer to Byte Array
int uid = 1000;
byte[] buffer = new byte[4];
buffer[0] = (byte) (uid >> 0);
buffer[1] = (byte) (uid >> 8);
buffer[2] = (byte) (uid >> 16);
buffer[3] = (byte) (uid >> 24);

// Byte Array to Integer
uid = 0;
uid += buffer[0] &  0xFF;
uid += buffer[1] << 8;
uid += buffer[2] << 16;
uid += buffer[3] << 24;

Pasos para convertir Entero => Arreglo Byte:

  1. Lo primero a realizar es convertir el entero de decimal a binario. En este caso el numero 1000b10 se representa en binario como 00000000 00000000 00000011 11101000b2.
  2. El siguiente paso es asignar un valor a cada byte dentro del arreglo. Siendo en este caso el indice 0 del arreglo la posicion en donde se encuentra el LSB (Least Significant Byte). En Little-endian este seria el byte en la menor posicion (a).
  3. Siendo esto entonces asignamos el valor total de 00000000 00000000 00000011 11101000b2 al primer indice. Como es un arreglo de bytes, este solo puede almacenar un octeto de bits (1 byte) por lo que en Java se trunca el numero de derecha a izquierda. Entonces se almacena el numero 11101000b2, el cual equivale a 232b10. En Java se manejan numeros con signos por lo que si mostramos el contenido de este indice nos mostrar√° -24b10 el cual es su representacion. En Java se almacenan valores desde -2^7 hasta (2^7 - 1) dentro de un byte. Por lo que usando el complemento de 2 tenemos que 232b10 se representan como -24b10. El byte se encuentra en la posicion (a) Little-endian.
    Complemento de 2:
    11101000 (232b10)
    - 00000001 (1b10)
    --------
    11100111 (231b10)
    --------
    00011000 (-24b10)
    Se aplica el complemento de 1 y se toma el MSB (Most Significant Bit) como signo. En este caso 1 = Negativo.
  4. Luego pasamos a almacenar el segundo byte, siempre en formato Little-endian, y este seria (a+1). Este byte ira en el indice 1 del arreglo. Para almacenar el segundo octeto lo que se hace es hacer un "Signed Bit-Shift" de 8 lugares hacia la derecha en el numero original. Entonces seria 00000000 00000000 00000011 11101000b2 >> 8 = 00000011b2 = 3b10 y se almacena.
  5. Ahora pasamos al almacenar el tercer byte, en formato Little-endian (a+2). Este byte ira en el indice 2 del arreglo. Para almacenar el tercer octeto hacemos un Signed Bit-Shift de 16 lugares hacia la derecha sobre el numero original. Entonces seria 00000000 00000000 00000011 11101000b2 >> 16 = 00000000b2 = 0b10 y se almacena.
  6. Por ultimo pasamos a almacenar el cuarto y ultimo byte, el que se encuentra en la posicion (a+3). Este byte ira en el indice 3 del arreglo. Para almacenar el cuarto octeto hacemos un Signed Bit-Shift de 24 lugares hacia la derecha sobre el numero original. Entonces seria 00000000 00000000 00000011 11101000b2 >> 24 = 00000000b2 = 0b10 y se almacena.
  7. De esta forma logramos almacenar el entero 00000000 00000000 00000011 11101000b2 (32bit) en un arreglo de 4 elementos de 8bit cada uno.
    Grafica: (Little-endian)
    [0] => 11101000 Least Significant Byte - Lowest Memory Address = a
    [1] => 00000011 Memory Address = a+1
    [2] => 00000000 Memory Address = a+2
    [3] => 00000000 Most Significant Byte - Highest Memory Address = a+3

Pasos para convertir Arreglo Byte => Entero:

Antes que nada tenemos que tener en cuenta que Java convierte todos los datos numericos al mayor denominador de todos. Es decir cuando el resultado de operaciones debe ser entero, Java transforma todos los demas datos numericos a entero. Ejemplo: uid += buffer[0] => En este caso buffer[0] se convierte a entero para poder sumar con uid.

  1. Para realizar la conversion tenemos que tomar en cuenta lo estipulado arriba. Lo primero a hacer es convertir el primer indice (0) del arreglo a un entero y convertirlo a su valor original para luego sumar al entero destino. En este caso el valor de buffer[0] es 11101000b2 = 232b10, el cual equivale a -24. Java no trata de asignar el valor positivo del byte, sino que preserva el valor original de -24. Por lo que en un entero de 32bits -24 se representa de la sgte. forma: 11111111 11111111 11111111 11101000b2 = 4.294.967.272b10 que se representa como -24b10. De este numero entero solo nos interesa el ultimo octeto, el LSB.
    Entonces se realiza la sgte. operacion: buffer[0] & 0xFF
      1111 1111 1111 1111 1111 1111 1110 1000b2 (4.294.967.272b10)
    & 0000 0000 0000 0000 0000 0000 1111 1111b2 (255b10)
    -----------------------------------------
    0000 0000 0000 0000 0000 0000 1110 1000b2 (232b10)
    De esta forma recuperamos el octeto en la menor posicion (a) siempre utilizando Little-endian. Se suma 232b10 al entero.
  2. Ahora tenemos que recuperar el segundo octeto. Para esta tarea tenemos que hacer un Bit-Shift[*1] de 8 lugares hacia la izquierda sobre el valor de buffer[1].
    Entonces seria: buffer[1] << 8
    00000000 00000000 00000000 00000011b2 (3b10) << 8 = 00000000 00000000 00000011 00000000b2 (768b10)
    De esta forma recuperamos el octeto en la posicion (a+1) siempre utilizando Little-endian. Se suma 768b10 al entero.
  3. Ahora tenemos que recuperar el tercer octeto. Para esta tarea tenemos que hacer un Bit-Shift[*1] de 16 lugares hacia la izquierda sobre el valor de buffer[2].
    Entonces seria: buffer[2] << 16
    00000000 00000000 00000000 00000000b2 (0b10) << 16 = 00000000 00000000 00000000 00000000b2 (0b10)
    De esta forma recuperamos el octeto en la posicion (a+2) siempre utilizando Little-endian. Se suma 0b10 al entero.
  4. Por ultimo tenemos que recuperar el cuarto octeto. Para esta tarea tenemos que hacer un Bit-Shift[*1] de 24 lugares hacia la izquierda sobre el valor de buffer[3].
    Entonces seria: buffer[3] << 24
    00000000 00000000 00000000 00000000b2 (0b10) << 24 = 00000000 00000000 00000000 00000000b2 (0b10)
    De esta forma recuperamos el octeto en la posicion (a+3) siempre utilizando Little-endian. Se suma 0b10 al entero.

Conclusion:

De esta forma es posible convertir de un entero de 32bits a un arreglo de 4 bytes en Java.

Notas

  1. En Java no existe el operador <<< que seria Unsigned Bit-Shift a la izquierda. Por lo que el operador << hace un Bit-Shift a la izquierda sin importar el signo.