¿Comparar dos matrices de bytes? (Java)

96

Tengo una matriz de bytes con una ~ secuencia binaria conocida en ella. Necesito confirmar que la secuencia binaria es lo que se supone que es. Lo he intentado .equalsademás ==, pero ninguno funcionó.

byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
if (new BigInteger("1111000011110001", 2).toByteArray() == array){
    System.out.println("the same");
} else {
    System.out.println("different'");
}
Roger
fuente
¿Puedes comparar las cadenas directamente?
Objetos
1
@objects - ceros iniciales. Además, las cosas de String / BigInteger podrían ser solo una forma de ilustrar la pregunta de comparación de matriz de bytes.
Stephen C
¿Ha intentado utilizar el método compareTo? Por cierto, ==compara valores primitivos solo para tu información
ChriskOlson
Aquí hay una pregunta relacionada sobre la comparación de matrices parciales: stackoverflow.com/questions/16646967/…
Vadzim

Respuestas:

165

En su ejemplo, tiene:

if (new BigInteger("1111000011110001", 2).toByteArray() == array)

Cuando se trata de objetos, ==en Java se comparan valores de referencia . Está comprobando si la referencia a la matriz devuelta por toByteArray()es la misma que la referencia contenida array, lo que, por supuesto, nunca puede ser cierto. Además, las clases de matriz no se anulan, .equals()por lo que el comportamiento es el Object.equals()que también solo compara los valores de referencia.

Para comparar el contenido de dos matrices, la clase Arrays proporciona métodos de comparación de matrices estáticas

byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
byte[] secondArray = new BigInteger("1111000011110001", 2).toByteArray();
if (Arrays.equals(array, secondArray))
{
    System.out.println("Yup, they're the same!");
}
Brian Roach
fuente
11

Java no sobrecarga a los operadores, por lo que normalmente necesitará un método para tipos no básicos. Prueba el método Arrays.equals () .

jswolf19
fuente
11

Puede usar ambos Arrays.equals()y MessageDigest.isEqual(). Sin embargo, estos dos métodos tienen algunas diferencias.

MessageDigest.isEqual()es un método de comparación constante en el tiempo y Arrays.equals()no es constante en el tiempo y puede traer algunos problemas de seguridad si lo usa en una aplicación de seguridad.

Los detalles de la diferencia se pueden leer en Arrays.equals () vs MessageDigest.isEqual ()

PixelsTech
fuente
3

Por supuesto, la respuesta aceptada de Arrays.equal (byte [] primero, byte [] segundo) es correcta. Me gusta trabajar en un nivel inferior, pero no pude encontrar una función eficiente de bajo nivel para realizar rangos de prueba de igualdad. Tuve que preparar el mío, si alguien lo necesita:

public static boolean ArraysAreEquals(
 byte[] first,
 int firstOffset,
 int firstLength,
 byte[] second,
 int secondOffset,
 int secondLength
) {
    if( firstLength != secondLength ) {
        return false;
    }

    for( int index = 0; index < firstLength; ++index ) {
        if( first[firstOffset+index] != second[secondOffset+index]) {
            return false;
        }
    }

    return true;
}
Bamaco
fuente
Esta es una buena solución para probar un subconjunto de las matrices en lugar de todo. Sin embargo, tenga en cuenta que Arrays.equals (byte [], byte []) hace casi exactamente todo lo que hizo aquí (excepto que maneja los dos valores siendo el mismo objeto de manera más eficiente y maneja arreglos nulos que se pasan con gracia). Cuando se me dé la opción de usar una implementación de biblioteca estándar que será respaldada por la comunidad o escribir una implementación personalizada de la misma que necesitaré soportar para siempre, elegiré la primera cada vez.
Tom Dibble
4
La respuesta es útil para el caso de uso en el que uno tiene dos matrices y desea comparar el rango de bytes de ellas, sin hacer primero copias de las matrices. Las copias de matriz agregan sobrecarga, agregan basura y no son necesarias. Lo que necesitaba era un memcmp () de estilo c de bajo nivel y esto se ajusta a la necesidad. Por supuesto, memcmp () solo toma 1 argumento de longitud. Esta función está lo suficientemente cerca.
Bamaco
2

Como quería comparar dos matrices para una prueba unitaria y llegué a esta respuesta, pensé que podía compartir.

También puedes hacerlo con:

@Test
public void testTwoArrays() {
  byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
  byte[] secondArray = new BigInteger("1111000011110001", 2).toByteArray();

  Assert.assertArrayEquals(array, secondArray);
}

Y puede consultar Comparación de matrices en aserciones JUnit para obtener más información.

Sylhare
fuente