Entero Java a conjunto de bytes

Respuestas:

293

Usar ByteBuffer de Java NIO es muy simple:

byte[] bytes = ByteBuffer.allocate(4).putInt(1695609641).array();

for (byte b : bytes) {
   System.out.format("0x%x ", b);
}

salida:

0x65 0x10 0xf3 0x29 
dfa
fuente
44
O utilice el formato "0x%02X"si siempre desea dos caracteres hexadecimales, así como hexadecimales en mayúsculas, por ejemplo, System.out.format("0x%02X", (byte) 10)pantallas 0x0A.
Maarten Bodewes
12
Puede usar Integer.SIZE / 8 para evitar codificar el 4, que es un patrón que funciona bien para otros tipos como Long.
davenpcj 05 de
3
@davenpcj Incluso puedes usar Integer.SIZE / Byte.SIZE
rkosegi
11
@rkosegi O incluso Integer.BYTES desde Java 8 :)
drvdijk
1
El hilo de @MaartenBodewes no tiene nada que ver con el formato visible, pero la operación de tipo nativo
Jacek Cz
146

Qué tal si:

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

La idea no es mía . Lo tomé de alguna publicación en dzone.com .

Grzegorz Oledzki
fuente
44
Veo su punto, pero para esta tarea en particular, 'mi' código es más declarativo y claro que un ByteBuffer 'mágico', que hay que verificar para ver qué hace.
Grzegorz Oledzki
24
@Kevin, eso es muy duro, hay muchos casos en los que este tipo de código es apropiado, por ejemplo, en el procesamiento de imágenes. Las bibliotecas JDK son geniales en general, pero no cubren y / o no están optimizadas para todos los casos de uso.
mikera
14
convenido; La sobrecarga y la complejidad de ByteBuffer pueden no ser apropiadas en comparación con algunas operaciones de byte simples y bien conocidas.
swdunlop
66
Otro punto que agregaría es que ha utilizado el operador de desplazamiento a la derecha sin firmar en >>>lugar del operador de desplazamiento a la derecha >>( docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html ) por lo que el comportamiento puede no ser el deseado / como se esperaba con números con y sin signo
RobV
44
Este enfoque parece ser un poco más rápido que los métodos ByteBuffer o BigInteger mencionados. Algo más a tener en cuenta si va a hacer muchas conversiones.
buscador
45

BigInteger.valueOf(1695609641).toByteArray()

vmpn
fuente
2
¿Qué garantía tiene de que producirá una matriz de 4 bytes?
MeBigFatGuy
2
Exactamente lo que escribió MeBigFatGuy. Javadoc de BigInteger.toByteArray()estados: "La matriz contendrá el número mínimo de bytes necesarios para representar este BigInteger ..."
icza
2
¿Dónde en la pregunta pide que la matriz de bytes sea de longitud fija 4? Dependiendo del algoritmo, esto debe ser parte de usted, puede utilizar la longitud de la matriz
vmpn
Esto es mucho más dinámico y debería ser la respuesta correcta. Simplemente puede hacer una adición de matriz para crear el tamaño deseado si lo desea. Especialmente cuando tienes que considerar los valores int con signo de Java.
Droid Chris
2
Esto parece crear un byte para 0x7f y dos bytes para 0x80 (los dos bytes son: 0x0 0x80).
Scot
26
byte[] IntToByteArray( int data ) {    
    byte[] result = new byte[4];
    result[0] = (byte) ((data & 0xFF000000) >> 24);
    result[1] = (byte) ((data & 0x00FF0000) >> 16);
    result[2] = (byte) ((data & 0x0000FF00) >> 8);
    result[3] = (byte) ((data & 0x000000FF) >> 0);
    return result;        
}
Yury Finchenko
fuente
22

Usando guayaba :

byte[] bytearray = Ints.toByteArray(1695609641);
Aleksandr Dubinsky
fuente
7
byte[] conv = new byte[4];
conv[3] = (byte) input & 0xff;
input >>= 8;
conv[2] = (byte) input & 0xff;
input >>= 8;
conv[1] = (byte) input & 0xff;
input >>= 8;
conv[0] = (byte) input;
Carl Smotricz
fuente
2
Eso extrae los 8 bytes menos significativos. También evita arrastrar el signo del número de entrada al octeto convertido.
Carl Smotricz
stackoverflow.com/questions/35305634/… - ¿puede resolver este C # en Java?
5
public static byte[] intToBytes(int x) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(bos);
    out.writeInt(x);
    out.close();
    byte[] int_bytes = bos.toByteArray();
    bos.close();
    return int_bytes;
}
lyon819
fuente
4

Los fragmentos a continuación funcionan al menos para enviar un int sobre UDP.

int a la matriz de bytes:

public byte[] intToBytes(int my_int) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutput out = new ObjectOutputStream(bos);
    out.writeInt(my_int);
    out.close();
    byte[] int_bytes = bos.toByteArray();
    bos.close();
    return int_bytes;
}

matriz de bytes a int:

public int bytesToInt(byte[] int_bytes) throws IOException {
    ByteArrayInputStream bis = new ByteArrayInputStream(int_bytes);
    ObjectInputStream ois = new ObjectInputStream(bis);
    int my_int = ois.readInt();
    ois.close();
    return my_int;
}
HaoQi Li
fuente
44
El uso de ObjectOutputStream es incorrecto. Use DataOutputStream, el uso de OOS hace que la matriz de bytes no sea de 4 bytes.
MeBigFatGuy
2

Debido a que generalmente desea convertir esta matriz nuevamente en un int en un punto posterior, estos son los métodos para convertir una matriz de entradas en una matriz de bytes y viceversa:

public static byte[] convertToByteArray(final int[] pIntArray)
{
    final byte[] array = new byte[pIntArray.length * 4];
    for (int j = 0; j < pIntArray.length; j++)
    {
        final int c = pIntArray[j];
        array[j * 4] = (byte)((c & 0xFF000000) >> 24);
        array[j * 4 + 1] = (byte)((c & 0xFF0000) >> 16);
        array[j * 4 + 2] = (byte)((c & 0xFF00) >> 8);
        array[j * 4 + 3] = (byte)(c & 0xFF);
    }
    return array;
}

public static int[] convertToIntArray(final byte[] pByteArray)
{
    final int[] array = new int[pByteArray.length / 4];
    for (int i = 0; i < array.length; i++)
        array[i] = (((int)(pByteArray[i * 4]) << 24) & 0xFF000000) |
                (((int)(pByteArray[i * 4 + 1]) << 16) & 0xFF0000) |
                (((int)(pByteArray[i * 4 + 2]) << 8) & 0xFF00) |
                ((int)(pByteArray[i * 4 + 3]) & 0xFF);
    return array;
}

Tenga en cuenta que debido a la propagación de signos y demás, se necesitan "& 0xFF ..." al convertir de nuevo a int.

jytou
fuente
1
integer & 0xFF

para el primer byte

(integer >> 8) & 0xFF

para el segundo y bucle, etc., escribir en una matriz de bytes preasignada. Un poco desordenado, desafortunadamente.

Brian Agnew
fuente
1

La clase org.apache.hadoop.hbase.util.Bytes tiene muchos métodos prácticos de conversión de bytes [], pero es posible que no desee agregar todo el jar de HBase a su proyecto solo para este propósito. Es sorprendente que no solo falte AFAIK de este método del JDK, sino también de bibliotecas obvias como commons io.

mlohbihler
fuente
1

Mi intento:

public static byte[] toBytes(final int intVal, final int... intArray) {
    if (intArray == null || (intArray.length == 0)) {
        return ByteBuffer.allocate(4).putInt(intVal).array();
    } else {
        final ByteBuffer bb = ByteBuffer.allocate(4 + (intArray.length * 4)).putInt(intVal);
        for (final int val : intArray) {
            bb.putInt(val);
        }
        return bb.array();
    }
}

Con ella puedes hacer esto:

byte[] fourBytes = toBytes(0x01020304);
byte[] eightBytes = toBytes(0x01020304, 0x05060708);

La clase completa está aquí: https://gist.github.com/superbob/6548493 , admite la inicialización desde cortos o largos

byte[] eightBytesAgain = toBytes(0x0102030405060708L);
superbob
fuente
1

Si estás usando apache-commons

public static byte[] toByteArray(int value) {
    byte result[] = new byte[4];
    return Conversion.intToByteArray(value, 0, result, 0, 4);
}
Neeraj
fuente