Порівняти два байтові масиви? (Java)


96

У мене є байтовий масив із ~ відомою двійковою послідовністю. Мені потрібно підтвердити, що двійкова послідовність є такою, якою вона повинна бути. Я пробував .equalsдодатково ==, але жоден з них не працював.

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

Ви можете просто порівняти рядки безпосередньо?
об'єкти

1
@objects - провідні нулі. Крім того, String / BigInteger може бути просто способом проілюструвати питання порівняння байтових масивів.
Stephen C

Ви пробували використовувати метод compareTo? BTW ==порівнює примітивні значення просто fyi
ChriskOlson

Ось пов'язане питання про часткове масиві порівняти: stackoverflow.com/questions/16646967 / ...
Vadzim

Відповіді:


165

У вашому прикладі ви маєте:

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

Коли мова йде про об’єкти, ==у Java порівнюються посилальні значення . Ви перевіряєте, чи посилання на масив, що повертається, toByteArray()є однаковим із посиланням, що зберігається в array, що, звичайно, ніколи не може бути істинним. Крім того, класи масивів не перевизначають, .equals()тому поведінка така, Object.equals()що також лише порівнює посилальні значення.

Для порівняння вмісту двох масивів у класі 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 не перевантажує оператори, тому зазвичай вам знадобиться метод для неосновних типів. Спробуйте метод Arrays.equals () .


11

Ви можете використовувати обидва Arrays.equals()і MessageDigest.isEqual(). Ці два методи мають деякі відмінності.

MessageDigest.isEqual()є методом порівняння, постійним у часі, і Arrays.equals()не є постійним у часі, і це може спричинити деякі проблеми безпеки, якщо ви використовуєте його в додатку безпеки.

Деталі різниці можна прочитати на Arrays.equals () проти MessageDigest.isEqual ()


3

Звичайно, прийнята відповідь Arrays.equal (байт [] по-перше, байт [] по-друге) є правильною. Мені подобається працювати на нижчому рівні, але мені не вдалося знайти ефективну функцію низького рівня для виконання діапазонів тесту на рівність. Мені довелося підбивати своє, якщо комусь це потрібно:

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

Це хороше рішення для тестування підмножини масивів, а не всієї справи. Однак зверніть увагу, що Arrays.equals (байт [], байт []) робить майже все, що ви робили тут (за винятком того, що ефективніше обробляє два значення, що є одним і тим же об’єктом, і обробляє нульові масиви, які передаються витончено). Отримавши вибір використовувати стандартну бібліотечну реалізацію, яка буде підтримана спільнотою, або написати власну реалізацію, яку мені потрібно буде підтримувати вічно, я кожного разу вибираю першу.
Том Діббл,

4
Відповідь корисна у випадку використання, коли один має два масиви і хоче порівняти діапазон байтів з них, без попереднього копіювання масивів. Копії масивів додають накладні витрати, додають сміття і не потрібні. Мені потрібен був низький рівень c стилю memcmp (), і це відповідає потребі. Звичайно, memcmp () приймає лише 1 аргумент довжини. Ця функція досить близька.
Бамако,

2

Оскільки я хотів порівняти два масиви для одиничного тесту, і я прийшов до цієї відповіді, я думав, що можу поділитися.

Ви також можете зробити це за допомогою:

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

  Assert.assertArrayEquals(array, secondArray);
}

І ви можете перевірити порівняння масивів у твердженнях JUnit для отримання додаткової інформації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.