Confronta due array di byte? (Giava)


96

Ho un array di byte con una sequenza binaria nota al suo interno. Devo confermare che la sequenza binaria è ciò che dovrebbe essere. Ho provato .equalsin aggiunta a ==, ma nessuno dei due ha funzionato.

byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
if (new BigInteger("1111000011110001", 2).toByteArray() == array){
    System.out.println("the same");
} else {
    System.out.println("different'");
}

puoi semplicemente confrontare le stringhe direttamente?
oggetti

1
@objects - zeri iniziali. Inoltre, il materiale String / BigInteger potrebbe essere solo un modo per illustrare la domanda di confronto tra array di byte.
Stephen C

Hai provato a utilizzare il metodo compareTo? BTW ==confronta i valori primitivi solo fyi
ChriskOlson

Ecco la domanda correlata sul confronto parziale degli array: stackoverflow.com/questions/16646967/…
Vadzim

Risposte:


165

Nel tuo esempio, hai:

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

Quando si tratta di oggetti, ==in java confronta i valori di riferimento . Stai controllando se il riferimento all'array restituito da toByteArray()è lo stesso del riferimento contenuto array, il che ovviamente non può mai essere vero. Inoltre, le classi di array non sovrascrivono .equals()quindi il comportamento è quello di Object.equals()cui confronta anche solo i valori di riferimento.

Per confrontare il contenuto di due array, i metodi di confronto degli array statici vengono forniti dalla 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!");
}


11

Java non sovraccarica gli operatori, quindi di solito avrai bisogno di un metodo per i tipi non di base. Prova il metodo Arrays.equals () .


11

Puoi usare sia Arrays.equals()e MessageDigest.isEqual(). Questi due metodi presentano tuttavia alcune differenze.

MessageDigest.isEqual()è un metodo di confronto costante di tempo e Arrays.equals()non è costante di tempo e può portare alcuni problemi di sicurezza se lo usi in un'applicazione di sicurezza.

I dettagli per la differenza possono essere letti su Arrays.equals () vs MessageDigest.isEqual ()


3

Ovviamente, la risposta accettata di Arrays.equal (byte [] primo, byte [] secondo) è corretta. Mi piace lavorare a un livello inferiore, ma non sono riuscito a trovare una funzione efficiente di basso livello per eseguire intervalli di test di uguaglianza. Ho dovuto preparare il mio, se qualcuno ne avesse bisogno:

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

Questa è una buona soluzione per testare un sottoinsieme degli array piuttosto che l'intera cosa. Tuttavia, nota che Arrays.equals (byte [], byte []) fa praticamente esattamente tutto ciò che hai fatto qui (tranne che gestisce i due valori che sono lo stesso oggetto in modo più efficiente e gestisce gli array nulli che vengono passati con garbo). Quando mi viene data la possibilità di utilizzare un'implementazione della libreria standard che sarà supportata dalla comunità o di scriverne un'implementazione personalizzata che dovrò supportare per sempre, sceglierò la prima volta ogni volta.
Tom Dibble,

4
La risposta è utile per il caso d'uso in cui si hanno due array e si desidera confrontare l'intervallo di byte da essi, senza prima fare copie degli array. Le copie di array aggiungono overhead, aggiungono spazzatura e non sono necessarie. Quello di cui avevo bisogno era un memcmp () in stile c di basso livello e questo si adatta alle necessità. Ovviamente, memcmp () accetta solo 1 argomento di lunghezza. Questa funzione è abbastanza vicina.
Bamaco

2

Dato che volevo confrontare due array per un test unitario e sono arrivato a questa risposta, ho pensato di poter condividere.

Puoi farlo anche con:

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

  Assert.assertArrayEquals(array, secondArray);
}

E potresti controllare Confronto di array nelle asserzioni di JUnit per maggiori informazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.