Comparar duas matrizes de bytes? (Java)

96

Eu tenho uma matriz de bytes com uma sequência binária conhecida. Preciso confirmar se a sequência binária é o que deveria ser. Eu tentei .equalsalém ==, mas nenhum funcionou.

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
fonte
você pode apenas comparar as cordas diretamente?
objeta
1
@objects - zeros à esquerda. Além disso, o material String / BigInteger poderia ser apenas uma forma de ilustrar a questão da comparação byte-array.
Stephen C
Você já tentou usar o método compareTo? BTW ==compara valores primitivos apenas fyi
ChriskOlson
Aqui está uma pergunta relacionada sobre a comparação parcial da matriz: stackoverflow.com/questions/16646967/…
Vadzim

Respostas:

165

Em seu exemplo, você tem:

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

Ao lidar com objetos, ==em java compara valores de referência . Você está verificando se a referência ao array retornado por toByteArray()é a mesma que a referência mantida array, o que, obviamente, nunca pode ser verdadeiro. Além disso, as classes de array não sobrescrevem, .equals()então o comportamento é aquele Object.equals()que também compara apenas os valores de referência.

Para comparar o conteúdo de duas matrizes, métodos de comparação de matrizes estáticas são fornecidos pela classe Arrays

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
fonte
64

Confira a java.util.Arrays.equals()família estática de métodos. Existe um que faz exatamente o que você deseja.

Ernest Friedman-Hill
fonte
11

Java não sobrecarrega os operadores, então você geralmente precisará de um método para tipos não básicos. Experimente o método Arrays.equals () .

jswolf19
fonte
11

Você pode usar Arrays.equals()e MessageDigest.isEqual(). Porém, esses dois métodos têm algumas diferenças.

MessageDigest.isEqual()é um método de comparação de constante de Arrays.equals()tempo e não e pode trazer alguns problemas de segurança se você usá-lo em um aplicativo de segurança.

Os detalhes da diferença podem ser lidos em Arrays.equals () vs MessageDigest.isEqual ()

PixelsTech
fonte
3

Obviamente, a resposta aceita de Arrays.equal (byte [] primeiro, byte [] segundo) está correta. Gosto de trabalhar em um nível inferior, mas não consegui encontrar uma função eficiente de nível inferior para realizar intervalos de teste de igualdade. Eu tive que preparar o meu próprio, se alguém precisar:

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
fonte
Esta é uma boa solução para testar um subconjunto dos arrays, em vez de tudo. No entanto, observe que Arrays.equals (byte [], byte []) faz quase exatamente tudo o que você fez aqui (exceto trata os dois valores sendo o mesmo objeto de forma mais eficiente e trata os arrays nulos que são passados ​​normalmente). Quando tiver a opção de usar uma implementação de biblioteca padrão que terá o suporte da comunidade ou de escrever uma implementação customizada dela que precisarei dar suporte para sempre, sempre escolherei a primeira.
Tom Dibble
4
A resposta é útil para o caso de uso em que se tem dois arrays e deseja comparar o intervalo de bytes deles, sem primeiro fazer cópias dos arrays. As cópias de matriz adicionam sobrecarga, adicionam lixo e não são necessárias. O que eu precisava era um memcmp () de estilo c de baixo nível e isso se encaixa na necessidade. Claro, memcmp () leva apenas 1 argumento de comprimento. Esta função está próxima o suficiente.
Bamaco
2

Como eu queria comparar dois arrays para um teste de unidade e cheguei a esta resposta, pensei que poderia compartilhar.

Você também pode fazer isso com:

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

  Assert.assertArrayEquals(array, secondArray);
}

E você pode verificar em Comparando arrays em asserções JUnit para obter mais informações.

Sylhare
fonte