Перейти к основному содержимому

Контрольные суммы в Java

· 3 мин. чтения

1. Обзор

В этой мини-статье мы дадим краткое объяснение того, что такое контрольные суммы, и покажем, как использовать некоторые встроенные функции Java для вычисления контрольных сумм .

2. Контрольные суммы и общие алгоритмы

По сути, контрольная сумма — это уменьшенное представление двоичного потока данных.

Контрольные суммы обычно используются в сетевом программировании для проверки того, что сообщение было получено полностью. При получении нового сообщения контрольную сумму можно пересчитать и сравнить с полученной контрольной суммой, чтобы убедиться, что ни один бит не был потерян. Кроме того, они также могут быть полезны для управления файлами, например, для сравнения файлов или обнаружения изменений.

Существует несколько распространенных алгоритмов создания контрольных сумм, таких как Adler32 и CRC32 . Эти алгоритмы работают путем преобразования последовательности данных или байтов в гораздо меньшую последовательность букв и цифр. Они спроектированы таким образом, что любое небольшое изменение входных данных приведет к совершенно другой расчетной контрольной сумме.

Давайте посмотрим на поддержку CRC32 в Java. Обратите внимание, что хотя CRC32 может быть полезен для контрольных сумм, он не рекомендуется для безопасных операций, таких как хеширование пароля .

3. Контрольная сумма из строки или массива байтов

Первое, что нам нужно сделать, это получить входные данные для алгоритма контрольной суммы.

Если мы начинаем со String , мы можем использовать метод getBytes() для получения массива байтов из String :

String test = "test";
byte[] bytes = test.getBytes();

Далее мы можем вычислить контрольную сумму, используя массив байтов:

public static long getCRC32Checksum(byte[] bytes) {
Checksum crc32 = new CRC32();
crc32.update(bytes, 0, bytes.length);
return crc32.getValue();
}

Здесь мы используем встроенный в Java класс CRC32 . После создания экземпляра класса мы используем метод update для обновления экземпляра Checksum байтами из ввода.

Проще говоря, метод обновления заменяет байты, хранящиеся в объекте CRC32 , — это помогает повторно использовать код и устраняет необходимость создания новых экземпляров контрольной суммы. Класс CRC32 предоставляет несколько переопределенных методов для замены либо всего массива байтов, либо нескольких байтов внутри него. ``

Наконец , после установки байтов мы экспортируем контрольную сумму с помощью метода getValue .

4. Контрольная сумма из InputStream

При работе с большими наборами двоичных данных описанный выше подход не будет очень эффективным с точки зрения использования памяти, поскольку каждый байт загружается в память .

Когда у нас есть InputStream , мы можем использовать CheckedInputStream для создания нашей контрольной суммы . Используя этот подход, мы можем определить, сколько байтов обрабатывается в любой момент времени.

В этом примере мы обрабатываем заданное количество байтов за раз, пока не достигнем конца потока.

Затем значение контрольной суммы доступно из CheckedInputStream :

public static long getChecksumCRC32(InputStream stream, int bufferSize) 
throws IOException {
CheckedInputStream checkedInputStream = new CheckedInputStream(stream, new CRC32());
byte[] buffer = new byte[bufferSize];
while (checkedInputStream.read(buffer, 0, buffer.length) >= 0) {}
return checkedInputStream.getChecksum().getValue();
}

5. Вывод

В этом руководстве мы рассмотрим, как генерировать контрольные суммы из байтовых массивов и InputStream с использованием поддержки Java CRC32.

Как всегда, код доступен на GitHub .