Entero Java a conjunto de bytes


190

Tengo un número entero: 1695609641

cuando uso el método:

String hex = Integer.toHexString(1695609641);
system.out.println(hex); 

da:

6510f329

pero quiero una matriz de bytes:

byte[] bytearray = new byte[] { (byte) 0x65, (byte)0x10, (byte)0xf3, (byte)0x29};

¿Cómo puedo hacer esto?



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 

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 .


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()


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;        
}


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;

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;
}

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;
}

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.


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.


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.


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);

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);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.