Quiero realizar una conversión sin recurrir a ningún truco dependiente de la implementación. ¿Algun consejo?¿Cómo puedo convertir una matriz de 4 bytes en un número entero?
Respuesta
lo que necesita saber el orden de bits de los bytes.
Suponiendo (como @ WhiteFang34) que bytes
es un byte[]
de longitud 4, entonces ...
Big-endian:
int x = java.nio.ByteBuffer.wrap(bytes).getInt();
ascendente hacia la izquierda:
int x = java.nio.ByteBuffer.wrap(bytes).order(java.nio.ByteOrder.LITTLE_ENDIAN).getInt();
+1 esto funciona y proporciona una buena opción para el soporte de little-endian. Me preguntaba si/dónde Java tenía soporte para hacer esto. Sin embargo, crea un objeto para seguir esta ruta. Por lo tanto, no es tan eficiente, aunque dudo que importe para la mayoría de los usos. – WhiteFang34
Suponiendo bytes
es una byte[4]
de un entero con el fin big endian, suele utilizarse en redes:
int value = ((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16)
| ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
El & 0xFF
son necesarios porque byte
se firmará en Java y necesita conservar el bit firmado aquí. Puede invertir el proceso con esta:
bytes[0] = (byte) ((value >> 24) & 0xFF);
bytes[1] = (byte) ((value >> 16) & 0xFF);
bytes[2] = (byte) ((value >> 8) & 0xFF);
bytes[3] = (byte) (value & 0xFF);
Podría estar malinterpretando, pero creo que eso es lo que escribes. –
@David: es. Gracias, de hecho lo etiqueté mal la primera vez. – WhiteFang34
¿Por qué se necesita el primer '& 0xff' cuando se convierte de' byte [] 'a' int'? ¿No están los primeros 1 para los valores firmados caídos por '<< 24'? Como lo entiendo '((bytes [0] & 0xFF) << 24)' es lo mismo que '((bytes [0] << 24)' en este caso. Si 'byte [0]' está firmado es convertido a int firmado pero '<< 24' lo elimina todo excepto los 8 bits del byte original. También creo que' & 0xff' se usa para soltar los bits iniciales con el valor 1 para los valores firmados para que no tengan ORed a 0 bits de operación anterior. ¿No está diciendo que '& 0xff' es necesario para retener el bit firmado incorrecto? – petrn
Es necesario especificar el orden de bytes de la matriz, pero suponiendo que el bytes[0]
es el byte más significativo a continuación:
int res = ((bytes[0] & 0xff) << 24) | ((bytes[1] & 0xff) << 16) |
((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff);
Este código es 100% portable, suponiendo que usa el algoritmo inverso para crear la matriz de bytes en primer lugar. surgen
problemas de orden de bytes en idiomas donde se puede emitidos entre un nativo de tipo entero y el byte tipo de matriz ... y luego descubrir que las diferentes arquitecturas de almacenar los bytes de un entero en diferentes órdenes.
No se puede hacer eso en Java. Entonces, para la comunicación de Java a Java, esto no debería ser un problema.
Sin embargo, si está enviando o recibiendo paquetes a alguna aplicación remota que se implementa en (digamos) C o C++, necesita "saber" qué orden de bytes se está utilizando en los paquetes de red. Algunas estrategias alternativas para saber/calcular esto son:
Todo el mundo utiliza "orden de red" (big-endian) para la materia en el alambre de acuerdo con el código de ejemplo anterior. Las aplicaciones que no son Java en máquinas little-endian necesitan voltear los bytes.
El emisor averigua el orden que espera el receptor y utiliza ese orden al ensamblar los datos.
El receptor averigua qué orden utilizó el emisor (por ejemplo, a través de un indicador en el paquete) y decodifica en consecuencia.
El primer enfoque es más simple y más ampliamente utilizado, aunque da lugar a 2 conversiones endian-ness innecesarios si tanto el emisor como el receptor están ascendente hacia la izquierda.
¿Hay alguna manera de hacer esto a través de la biblioteca estándar? No me siento demasiado bien asumiendo que las cosas son el orden de bytes de las máquinas a las que estoy enviando paquetes ... – Alex
@Alex: el orden de bytes de la máquina no importa en este cálculo, es el orden de bytes de su matriz lo que es importante. Deberá especificarlo incluso si use la biblioteca estándar (si hay un método estándar para hacer esto ... no recuerdo uno). –
Necesita '& 0xFF' cada uno de los bytes porque' byte' está firmado en Java. El bit firmado se interpone en el camino para cualquier número que use el primer bit de cualquiera de los bytes. P.ej. intente ir hacia atrás desde un entero como 384 a una matriz de bytes, cuando ejecute el código para recuperar el entero obtendrá -128 en lugar de 384. – WhiteFang34
No estoy seguro si esto es la sintaxis de Java correcto, pero ¿qué tal:
int value = 0;
for (i = 0; i <= 3; i++)
value = (value << 8) + (bytes[i] & 0xFF);
deberías '0xff' tus' bytes [i] 'porque un' byte' (en Java) puede ser negativo y Java convertirá tu byte en negativo entero en lugar de un valor entre 0-255 –
@Yanick: Gracias. He editado mi publicación con su corrección –
Esto no funciona, siempre devuelve 0. Necesita paréntesis para evitar la precedencia del operador: 'value = (value << 8) + (bytes [i] & 0xFF);' – WhiteFang34
public static int toInt(byte[] bytes) {
int result = 0;
for (int i=0; i<3; i++) {
result = (result << 8) - Byte.MIN_VALUE + (int) bytes[i];
}
return result;
}
Esto no funciona.Una matriz de bytes de todos los ceros devuelve 8421504. – WhiteFang34
¡Es una buena oportunidad! –
Asumiendo que su byte [] provienen de algún lugar, por ejemplo, una corriente que puede utilizar
DataInputStream dis = ... // can wrap a new ByteArrayInputStream(bytes)
int num = dis.readInt(); // assume big-endian.
o
ByteChannel bc = ... // can be a SocketChannel
ByteBuffer bb = ByteBuffer.allocate(64*1024);
bc.read(bb);
bb.flip();
if (bb.remaining()<4) // not enough data
int num = bb.getInt();
Al enviar datos, usted debe saber si va a enviar endian-endian grande o pequeña. Debes asumir otras cosas como si estás enviando un entero con signo de 4 bytes. Un protocolo binario está lleno de suposiciones. (Lo que lo hace más compacto y más rápido, pero más frágil que el texto)
Si no desea hacer tantas suposiciones, envíe un mensaje de texto.
'int num = dis.readInt(); // asumir big-endian. es información muy útil. –
también podemos utilizar después para que sea byte más dinámico tamaño de la matriz
Formato BigEndian:
public static int pareAsBigEndianByteArray(byte[] bytes) {
int factor = bytes.length - 1;
int result = 0;
for (int i = 0; i < bytes.length; i++) {
if (i == 0) {
result |= bytes[i] << (8 * factor--);
} else {
result |= bytes[i] << (8 * factor--);
}
}
return result;
}
pequeño formato Endian:
public static int pareAsLittleEndianByteArray(byte[] bytes) {
int result = 0;
for (int i = 0; i < bytes.length; i++) {
if (i == 0) {
result |= bytes[i] << (8 * i);
} else {
result |= bytes[i] << (8 * i);
}
}
return result;
}
Esto le ayuda mucho para la conversión de bytes a int valores
- 1. convertir un número entero en una matriz
- 2. Cómo convertir un entero a matriz de bytes en php
- 3. Cómo convierto una parte de una tupla de python (matriz de bytes) en un número entero
- 4. ¿Lees dos bytes en un número entero?
- 5. Java: Convertir bytes a entero
- 6. gran número entero de 4 bytes como sin firmar, binario
- 7. ¿Cómo puedo convertir un número entero en float en Java?
- 8. ¿Cómo puedo convertir un número entero en su representación verbal?
- 9. Cómo convertir un número entero de rubí en un símbolo
- 10. ¿Cómo convertir un entero a una matriz en PHP?
- 11. ¿Cómo puedo convertir un int a una matriz de bool?
- 12. Cómo convertir una matriz de bytes en una matriz int?
- 13. ¿Cómo convertir una matriz de bytes int a little endian?
- 14. ¿Cómo convertir una matriz de bytes en doble en C?
- 15. Cómo convertir un número entero en un vector binario?
- 16. Lectura de 3 bytes como un número entero
- 17. Convertir una matriz de bytes en un número decimal como una cadena
- 18. Java - ¿Convertir int a Byte Array de 4 bytes?
- 19. ¿Cómo convertir una matriz de bytes a una matriz int?
- 20. Cómo convertir imágenes en matriz de bytes
- 21. Lectura de bytes de tamaño "entero" de una matriz char *.
- 22. ¿Cómo puedo convertir un entero en una cadena Unicode en C?
- 23. Convertir 4 bytes a int
- 24. Convertir 3 bytes en un entero con signo en C#
- 25. Javascript - convertir entero en una matriz de bits
- 26. ¿Cómo agregar un número entero a una matriz?
- 27. impresión manual de un número entero de 0 bytes
- 28. C#: Convertir matriz de bytes en un flotador
- 29. Convertir una matriz de cadenas a matriz de bytes
- 30. En Java, ¿cómo puedo convertir un InputStream en una matriz de bytes (byte [])?
¿Qué desea convertir? Tu pregunta no es específica. ¿Cuáles son los cuatro bytes de tu matriz? – bmargulies